# ormar for Async Python APIs With Pydantic Models

> ormar is a small asynchronous Python ORM for PostgreSQL, MySQL, and SQLite, built around SQLAlchemy Core, Pydantic validation, and direct use in FastAPI. Its main trade-off is a smaller feature surface in exchange for one model definition across validation and database operations.

**ormar-orm/ormar** — python async orm with fastapi in mind and pydantic validation

- Repository: https://github.com/ormar-orm/ormar
- Website: https://collerek.github.io/ormar/
- Stars: 1,799 · Forks: 103
- Language: Python
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/ormar-orm-ormar

## ormar's Async Model for FastAPI Applications

ormar addresses a specific overlap in Python web applications: teams often maintain a Pydantic model for request parsing and response serialization, then maintain a separate ORM model for database access. The project places both responsibilities on one model definition by using Pydantic for validation and SQLAlchemy Core for database operations. That model can be used directly with FastAPI, while queries remain asynchronous and work with PostgreSQL, MySQL, and SQLite.

The target audience is therefore narrower than the general population of Python ORM users. FastAPI and Starlette developers are the clearest fit, particularly when they already accept asynchronous application code and want API schemas tied closely to database records. The repository also lists support through `fastapi-crudrouter` and `fastapi-pagination`, which extends the useful integration surface beyond hand-written query endpoints.

This is a mini ORM, not a drop-in replacement for the complete SQLAlchemy ORM. The distinction matters when planning an adoption. An application that relies on advanced mapping, session, identity-map, or query features from SQLAlchemy may find that SQLAlchemy Core plus a fuller ORM offers a better fit. ormar reduces model duplication, but it also asks developers to accept its narrower abstraction and asynchronous call model.

## SQLAlchemy Core, Pydantic, and Database Connections

The repository identifies three core dependencies. `sqlalchemy core` provides query construction, `sqlalchemy async` supplies cross-database asynchronous support, and `pydantic` handles data validation. This composition explains why ormar can expose database fields as validated Python attributes without asking the application to declare a second set of Pydantic classes beside its ORM classes.

Database access begins with an `OrmarConfig`. The configuration receives SQLAlchemy metadata and a `DatabaseConnection`. In the README's partial initialization, the URL uses the `sqlite+aiosqlite` driver, while synchronous SQLAlchemy is used to create tables from the same metadata. The model definitions would sit between configuration and table creation. The documentation deliberately labels this as a partial snippet and links to the migrations documentation for a complete application setup.

Because the database engine is asynchronous, ORM method calls must be awaited. FastAPI can manage that execution within its request lifecycle, but standalone Python scripts need an event-loop arrangement themselves. The README explicitly says that most interpreters do not permit `await` at the top level. This makes ormar suitable for async web frameworks, but it creates extra ceremony for command-line jobs, scripts, or synchronous services that are not designed around asyncio.

## Database Setup and Initial Table Creation

The README directs readers to its documentation for installation details, so it does not provide a general installation command that can be reproduced here. It does provide a database initialization pattern for tests and basic applications. This creates a SQLite database file through asynchronous ORM configuration, then uses synchronous SQLAlchemy metadata to create the tables.

The following is the README's partial snippet. It is not a complete application because the point marked for model definitions is intentionally omitted:

```python
import sqlalchemy
import ormar
from ormar import DatabaseConnection

DATABASE_URL = "sqlite+aiosqlite:///db.sqlite"
base_ormar_config = ormar.OrmarConfig(
    metadata=sqlalchemy.MetaData(),
    database=DatabaseConnection(DATABASE_URL),
)

# Define models here
```

After the omitted models are defined, the README creates the tables through a synchronous engine:

```python
engine = sqlalchemy.create_engine(DATABASE_URL.replace('+aiosqlite', ''))
base_ormar_config.metadata.create_all(engine)
```

The reader should expect a SQLite database at the URL's path after the documented creation step runs. For production code, the README instead recommends Alembic because `metadata.create_all()` does not provide the migration history and deployment process expected from a production schema. The project includes Alembic as a topic and links separate documentation for its configuration.

## Pydantic Validation at the API Boundary

ormar's defining design choice is that a database model also acts as a Pydantic model. FastAPI can use it for incoming request validation and outgoing response serialization, while ORM operations use the same field definitions for persistence. That removes the usual synchronization problem where a database column changes but a separately maintained request schema does not.

The benefit is strongest in small and medium APIs where the data model is straightforward and FastAPI already serves as the application boundary. The repository's stated goal is direct use of the model with FastAPI, and its supported integrations include `fastapi-crudrouter` and `fastapi-pagination`. A developer can therefore build CRUD-oriented endpoints without introducing a separate schema class for every record.

The trade-off is that sharing a model also couples database representation and API representation. If an endpoint accepts a shape that differs materially from a stored row, or if internal database fields must never become public response fields, a dedicated request or response schema may still be clearer. The README presents the one-model approach as a primary benefit but does not document a built-in policy for separating public and persistence-only fields.

## Async Constraints in Scripts and Web Services

The asynchronous design affects more than endpoint syntax. Every scheduled ORM call must be awaited, and standalone code must arrange execution in an asyncio-compatible function. FastAPI can handle that scheduling for request handlers, according to the README, so the tradeoff is mostly visible in scripts, background workers, notebooks, and services built without an async framework.

This also changes debugging and deployment expectations. An application must have an event-loop strategy and compatible database drivers. The project declares optional async drivers in `pyproject.toml`, including `aiosqlite`, `aiomysql`, `aiopg`, and `asyncpg`, with the visible portion showing version constraints for those packages. The database URL used by an application must therefore match both the selected backend and its available driver.

The repository does not claim that ormar makes synchronous Python code asynchronous. Nor does the README document a blocking compatibility layer. Engineers adopting it for an existing synchronous service should first identify how database calls are scheduled today. If the service has no asyncio event-loop design, the convenience of a shared FastAPI and Pydantic model may not compensate for that structural change.

## SQLAlchemy ORM Versus ormar's Smaller Surface

SQLAlchemy is the most relevant alternative because ormar itself builds on SQLAlchemy Core. A team already standardized on SQLAlchemy ORM can keep its established mapping and query model and use Pydantic separately, or add conversion logic between SQLAlchemy records and API schemas. That approach requires more explicit model coordination, but it exposes the full SQLAlchemy ORM rather than ormar's smaller abstraction.

ormar is the better conceptual fit when the application already uses FastAPI, wants Pydantic validation at the model layer, and can accept an asynchronous ORM designed around a limited feature set. SQLAlchemy ORM is the safer choice when the application depends on SQLAlchemy-specific behavior that ormar does not document, or when preserving an established database architecture matters more than eliminating duplicate schemas.

The repository also mentions `sqlalchemy-to-ormar`, a beta translation tool for converting existing SQLAlchemy ORM models and, when paired with `sqlacodegen`, generating ormar models from an existing database. That can reduce initial translation work, but its beta status means migration output should be reviewed rather than accepted without inspection.

## Release History, Dependencies, and Upgrade Boundaries

The project is not archived, and its last push was on 2026-10-16. Recent releases include 0.26.0 on 2026-06-08, 0.25.0 on 2026-05-07, and 0.24.0 on 2026-04-22. The 0.25.0 release notes describe a major performance update involving dumping data to IDs instead of nested models, while 0.26.0 lists bug fixes and table SQL comments. Those changes make release review relevant to serialization behavior, query output, and schema expectations.

The visible `pyproject.toml` declares Python `^3.10.0`, Pydantic `>=2.11.9,<2.14`, and SQLAlchemy `^2.0.40` with the `asyncio` extra. A comment states that ormar relies on Pydantic internals, so the upper Pydantic bound should be checked before upgrading that dependency. The project also provides optional database drivers with bounded version ranges. Pinning dependencies is explicitly recommended in the README.

Ormar's versioning policy distinguishes breaking changes from non-breaking changes and advises reading release notes before updating. That does not remove upgrade work: teams should check model serialization, database driver compatibility, migration behavior, and the changes documented for each release. The MIT license allows use and modification under its terms, but teams remain responsible for reviewing license obligations and compatibility separately from the library's technical behavior.

## Conclusion

ormar suits FastAPI and Starlette developers who want Pydantic-validated models to serve as both API schemas and database records. It is less suitable for applications that need a broad SQLAlchemy ORM feature set or cannot accommodate asynchronous execution. Before adoption, verify compatibility with the pinned Pydantic range, the selected database driver, Alembic migration setup, and the bug fixes and table SQL comments in release 0.26.0.

## FAQ

### How do I install ormar?

The README does not provide a general installation command. It directs users to the project documentation and links to PyPI through the package badge.

### Which databases does ormar support?

ormar supports PostgreSQL, MySQL, and SQLite. The project uses SQLAlchemy Core and SQLAlchemy async for cross-database support.

### Does ormar require SQLAlchemy models to be defined separately from Pydantic models?

No. The README presents ormar as a way to maintain one model rather than separate Pydantic and ORM models, with Pydantic handling validation and the model usable directly with FastAPI.

### How should production database changes be managed in ormar?

The README recommends Alembic for migrations and production database changes. It says SQLAlchemy table creation is sufficient for tests and basic applications.

### Is ormar suitable for synchronous Python scripts?

Not without additional event-loop handling. The README says ormar calls must be awaited and that standalone code needs to schedule execution manually, while FastAPI handles this for async request handlers.

## Sources

- [License: MIT](https://github.com/ormar-orm/ormar/blob/master/LICENSE)
- [ormar-orm/ormar on GitHub](https://github.com/ormar-orm/ormar)
- [Project website](https://collerek.github.io/ormar/)
- [README](https://github.com/ormar-orm/ormar/blob/master/README.md)
- [Releases](https://github.com/ormar-orm/ormar/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ormar-orm-ormar
