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.0

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.0
File Size Uploaded
fasorm-0.1.0.tar.gz 36.2 kB Details

Built distribution (wheel)

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

Total release size: 76.2 kB

Release files / fasorm-0.1.0.tar.gz

Download URL fasorm-0.1.0.tar.gz
Size 36.2 kB
Tags Source
SHA-256 checksum
How to use checksums
f76cb1643280fec18efa64d3dec126e16891c2ea21b6fd591d2be2209139ff23
BLAKE2b-256 checksum
How to use checksums
2e197d930f8dd04924eb3917c90995a3cbe0f4bc530d3c97f4b9f9b15410b4db
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.0-py3-none-any.whl

Download URL fasorm-0.1.0-py3-none-any.whl
Size 40.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dbc01b76c2d53c9711169d13aedabcbb5c177def5573c2ab49ec918881a081b6
BLAKE2b-256 checksum
How to use checksums
30c93f52684065a30cef5a2d53185b661ebe39c3c772ab7c092446f4f0074807
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

0.1.5

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

This release

0.1.0 This release

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