MetaORM¶
Async repository layer over SQLModel. Define a table, a repository with keyword arguments, and you have a complete async CRUD layer.
- Minimal API —
create_item,get_items,update_items,delete_items. That's it. - Built-in DTO mapping — return table instances directly or map to separate Pydantic models.
- Intuitive transactions — every CRUD call runs in a transaction; explicit
transaction()context manager for custom scopes. - Nested transactions (savepoints) —
nested_transaction()allows partial rollback inside a shared transaction. - Multi-repo atomic transactions —
RepositoriesContainerlets several repositories share one atomic transaction. - Filters, pagination, sorting — powered by
pydantic-filters. - Eager loading — pass SQLAlchemy
joinedload/selectinloadviaoptions.
Install¶
Requires Python >=3.12.
!!! note
The package is installed directly from GitHub because metaorm depends on a patched version of pydantic-filters that is not yet available on PyPI.
Quick start¶
from metaorm import BaseFilter, BaseRepository, BaseTable, RepositorySettings, Field
class UserTable(BaseTable, table=True):
__tablename__ = "users"
id: int | None = Field(default=None, primary_key=True)
name: str
email: str = Field(unique=True)
class UserFilter(BaseFilter):
name: str | None = None
email: str | None = None
class UserRepository(BaseRepository, table=UserTable, filter_=UserFilter):
pass
async def main():
repo = UserRepository(
settings=RepositorySettings(dsn="sqlite+aiosqlite:///:memory:"),
)
await repo.create_tables()
user = await repo.create_item(UserTable(name="Alice", email="alice@example.com"))
print(user.id, user.name)
all_users = [u async for u in repo.get_items()]
print(len(all_users))
Next steps¶
- Read the User Guide for detailed explanations.
- Browse the API Reference for auto-generated docs.
- Explore Examples for common patterns.