Files
awesome-python/website/data/category_intros/orm.md
T
Vinta ChenandClaude 2cc1bb440d docs: rewrite ORM category intro
The old intro told every FastAPI app to use SQLModel, which SQLModel's own docs don't claim beyond simple cases, and leaned on API names from SQLAlchemy's 2.0 rename (Mapped, mapped_column).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-26 22:09:22 +08:00

3.4 KiB

SQLAlchemy is the Python ORM for most projects, and Django projects use the Django ORM. On MongoDB, pick Beanie for async code and MongoEngine for sync.

How to choose:

  • A Django project: Django ORM
  • Any other app on a relational database: SQLAlchemy
  • A FastAPI app with simple tables: SQLModel
  • A small app that wants one module and no dependencies: peewee
  • MongoDB from async code: Beanie
  • MongoDB from sync code: MongoEngine
  • Amazon DynamoDB: PynamoDB

SQLAlchemy follows the data mapper pattern, so your classes and your schema can change separately. Open the Session in a with block, and keep its lifecycle outside the functions that read or write data: one Session per thread, one AsyncSession per task. To avoid N+1 queries, load related objects up front with eager loading.

The Django ORM follows the Active Record pattern: each model holds both the fields and the behavior of its data. Before you optimize, find out what queries you run and what they cost.

SQLModel is designed for FastAPI apps: one class is both a Pydantic model and a SQLAlchemy model. Get the session from a FastAPI dependency, so each request gets its own. When you need more complex features, plug SQLAlchemy in directly.

For a small app, peewee is a single module with no required dependencies, with few concepts to learn. In a web app, open a connection per request and close it when the request ends. Once traffic grows, switch to a pooled database.

On the NoSQL side, Beanie is an async MongoDB ODM built on Pydantic, with one Document class per collection. Pass your document models to init_beanie(), which creates the collections and the indexes you declared.

MongoEngine is the sync pick: it's built on PyMongo only and doesn't support async drivers. Its document schemas are enforced in your app, not by MongoDB, and they catch wrong types and missing fields.

PynamoDB is a Pythonic interface to DynamoDB. Build on its Model API: one model class per table, each with a hash key. For tests, point it at a local DynamoDB-compatible server.

Track schema changes in migrations: Django has them built in, SQLAlchemy has Alembic, and Beanie ships its own. Review every migration Alembic's autogenerate writes, since it's not meant to be perfect.