Skip to main content

FasORM

Laravel Eloquent-style ORM for FastAPI — expressive models, clean migrations, and an artisan-style CLI, powered by SQLAlchemy 2.0 & Alembic.

pip install fasorm

Quick Start

1. Initialise your project

fasorm init

Creates:

app/
    models/
    migrations/
    seeders/
.env
fasorm.config.py

2. Create a model

fasorm make:model User -m

Edit app/models/user.py:

from fasorm import Model, String, Boolean

class User(Model):
    name = String()
    email = String().unique()
    password = String()
    is_active = Boolean().default(True)

3. Edit the migration

app/migrations/2026_07_25_143000_create_users_table.py:

from fasorm.schema import Blueprint

def up(table: Blueprint):
    table.id()
    table.string("name")
    table.string("email").unique()
    table.string("password")
    table.boolean("is_active").default(True)
    table.timestamps()

def down(table: Blueprint):
    table.drop()

4. Run migrations

fasorm migrate
  FasORM  ·  Running migrations…

  3 migration(s) pending…

  ✅  2026_07_25_143000_create_users_table

  ✓  Migration successful. 1 migration(s) applied.

Models

Define a model

from fasorm import Model, String, Boolean, Timestamp, HasMany

class User(Model):
    name = String()
    email = String().unique()
    is_active = Boolean().default(True)
    posts = HasMany("Post")

Features:

  • Auto-generated id (BigInteger, autoincrement)
  • Auto-generated created_at and updated_at timestamps
  • Auto-generated __tablename__ from class name (User → users, BlogPost → blog_posts)

CRUD Operations

# Create
user = await User.create(name="Sandy", email="sandy@example.com")

# Find by ID
user = await User.find(1)
user = await User.find_or_fail(1)  # raises ModelNotFoundError

# Query
users = await User.where(is_active=True).get()
user = await User.where(email="sandy@example.com").first()
users = await User.where("age", ">=", 18).order_by("name").get()

# All
users = await User.all()

# Paginate
page = await User.paginate(per_page=20, page=1)

# Update
await user.update(name="New Name")

# Delete
await user.delete()

# First or create
user = await User.first_or_create(
    {"email": "sandy@example.com"},
    defaults={"name": "Sandy"}
)

# Update or create
user = await User.update_or_create(
    {"email": "sandy@example.com"},
    defaults={"name": "Updated Sandy"}
)

Relationships

from fasorm import Model, String, HasMany, BelongsTo

class User(Model):
    name = String()
    posts = HasMany("Post")

class Post(Model):
    title = String()
    user = BelongsTo("User")

# Eager loading
users = await User.with_("posts").get()

Serialisation

user.to_dict()   # → {"id": 1, "name": "Sandy", ...}
user.to_json()   # → '{"id": 1, "name": "Sandy", ...}'
page.to_dict()   # → {"data": [...], "meta": {"total": 100, ...}}

Field Types

Field SQL Type Notes
String(length=255) VARCHAR(n)
Text() TEXT
Integer() INTEGER
BigInteger() BIGINT
SmallInteger() SMALLINT
Float(precision) FLOAT
Decimal(precision, scale) NUMERIC(p,s)
Boolean() BOOLEAN
Date() DATE
Time() TIME
Timestamp() TIMESTAMP WITH TZ
Json() JSON / JSONB
Uuid() UUID / CHAR(36) Native on PG
Enum(values) ENUM
Vector(dimension) VECTOR(n) / TEXT pgvector on PG
Array(item_type) ARRAY / JSON Native on PG
Binary(length) LARGEBINARY

All fields support chaining: .nullable(), .unique(), .default(value), .index(), .comment(text)


CLI Commands

Command Description
fasorm init Scaffold project structure
fasorm make:model Name [-m] Create a model (optionally with migration)
fasorm make:migration name Create a migration file
fasorm make:seeder Name Create a seeder file
fasorm migrate Run pending migrations
fasorm rollback [--steps N] Rollback last N batches
fasorm refresh Rollback all + re-migrate
fasorm fresh [--seed] Drop all + migrate + seed
fasorm seed [--class Name] Run seeders
fasorm status Show migration status

FastAPI Integration

from fastapi import FastAPI, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from fasorm import get_session, init_db
from fasorm.config import load_config

app = FastAPI()

@app.on_event("startup")
async def startup():
    config = load_config()
    init_db(config)

@app.get("/users")
async def list_users():
    users = await User.all()
    return [u.to_dict() for u in users]

@app.get("/users/{user_id}")
async def get_user(user_id: int):
    user = await User.find_or_fail(user_id)
    return user.to_dict()

Architecture

                FastAPI
                   │
                FasORM
                   │
          ─────────┼─────────
          │                 │
      SQLAlchemy         Alembic
          │                 │
      PostgreSQL          SQLite
      MySQL               MariaDB

FasORM is an opinionated layer on top of SQLAlchemy 2.0 and Alembic — not a replacement.


License

MIT

Metadata

Release files for fasorm 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fasorm 0.1.5
File Size Uploaded
fasorm-0.1.5.tar.gz 37.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fasorm 0.1.5
File Interpreter ABI Platform
fasorm-0.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 78.6 kB

Release files / fasorm-0.1.5.tar.gz

Download URL fasorm-0.1.5.tar.gz
Size 37.6 kB
Tags Source
SHA-256 checksum
How to use checksums
2a8e9aa8c23a413551ae179b8ebfa02cefcb30b98fcd5d389908881d54137627
BLAKE2b-256 checksum
How to use checksums
d2420137b0b976b3eb2778d90354beef128aa722a2350eb627e94de71fc2efc3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release files / fasorm-0.1.5-py3-none-any.whl

Download URL fasorm-0.1.5-py3-none-any.whl
Size 41.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3a787759a42a7d3b4859551bdd93440e27d6025a097d1cd639ada4f538075f33
BLAKE2b-256 checksum
How to use checksums
a5ea6ff3e9835afcc048a2e8e6236431fb63f181829eaf237815969fcf634a3b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.4

Release history Release notifications | RSS feed

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

This release

0.1.5 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page