NEW: Fenrir v4.1.2 — 56 Bug Fixes, Performance Optimizations, 1331 Tests, 5-Framework Benchmark! Read the changelog
orm.md
docs orm.md

Lightweight ORM

Fenrir v4.1.2 includes a lightweight async ORM for SQLite and PostgreSQL databases.

Overview

The ORM provides:

  • SQLite & PostgreSQL: Support for both databases
  • Model with Metaclass: Declarative model definition
  • Field Types: Integer, String, Float, Boolean, Datetime, JSON
  • QuerySet: Chainable queries with filters, ordering, limit, offset
  • SQL Injection Prevention: Parameterized queries throughout
  • Async Support: Fully async database operations

Database Setup

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from fenrir.orm import Database

# SQLite
db = Database("sqlite:///app.db")

# PostgreSQL
db = Database("postgresql://user:pass@localhost/dbname")

# Connect before using
await db.connect()

Defining Models

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
from fenrir.orm import Model, fields

class User(Model):
    __tablename__ = "users"

    id = fields.Integer(primary_key=True)
    username = fields.String(max_length=100, unique=True)
    email = fields.String(max_length=255)
    age = fields.Integer(default=0)
    is_active = fields.Boolean(default=True)
    created_at = fields.Datetime(auto_now_add=True)
    metadata = fields.JSONField(default=dict)

class Post(Model):
    __tablename__ = "posts"

    id = fields.Integer(primary_key=True)
    title = fields.String(max_length=200)
    content = fields.Text()
    author_id = fields.Integer(foreign_key="users.id")
    published = fields.Boolean(default=False)

CRUD Operations

Create

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Create a new user
user = await User.create(
    username="john",
    email="john@example.com",
    age=25
)

# Bulk create
users = await User.bulk_create([
    {"username": "alice", "email": "alice@example.com"},
    {"username": "bob", "email": "bob@example.com"},
])

Read

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Get by ID
user = await User.get(id=1)

# Filter
active_users = await User.filter(is_active=True)

# Complex queries
users = await User.filter(
    age__gte=18,
    is_active=True
).order_by("username").limit(10).offset(0)

# Get or create
user, created = await User.get_or_create(
    username="john",
    defaults={"email": "john@example.com"}
)

Update

1
2
3
4
5
# Update single user
await User.filter(id=1).update(email="new@example.com")

# Bulk update
await User.filter(is_active=False).update(is_active=True)

Delete

1
2
3
4
5
# Delete by ID
await User.delete(id=1)

# Bulk delete
await User.filter(is_active=False).delete()

QuerySet Methods

1
2
3
4
5
6
7
8
9
# Chaining
queryset = User.filter(is_active=True)
queryset = queryset.order_by("-created_at")
queryset = queryset.limit(10)
queryset = queryset.offset(20)

# Aggregation
count = await User.filter(is_active=True).count()
exists = await User.filter(username="john").exists()

Field Types

1
2
3
4
5
6
7
8
9
fields.Integer(primary_key=True)      # Auto-increment integer
fields.Integer(default=0)             # Integer with default
fields.String(max_length=100)         # VARCHAR(100)
fields.Text()                         # TEXT
fields.Float(default=0.0)            # FLOAT
fields.Boolean(default=False)        # BOOLEAN
fields.Datetime(auto_now_add=True)   # Auto-set on create
fields.Datetime(auto_now=True)       # Auto-set on update
fields.JSONField(default=dict)       # JSON object

Database Operations

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Execute raw SQL
result = await db.execute("SELECT * FROM users WHERE id = ?", [1])

# Fetch all
rows = await db.fetch_all("SELECT * FROM users")

# Fetch one
row = await db.fetch_one("SELECT * FROM users WHERE id = ?", [1])

# Disconnect
await db.disconnect()
Edit on GitHub Last Updated: Oct 20, 2018
© 2026 Fenrir Project.
main*
v4.1.2
Ln 1, Col 1
UTF-8
Prettier
Light Mode
Markdown