Advanced Alchemy provides ready-to-go SQLAlchemy concoctions, simplifying common database operations and patterns. It's built on SQLAlchemy and offers robust repository and service layers, DTO generation, and integrates seamlessly with frameworks like Litestar. Key features include SQLModel compatibility, read/write replica routing, Dogpile caching, and enhanced CLI tools. Currently at version 1.9.3, it maintains an active release cadence with frequent updates and bug fixes.
Install & Compatibility
Where this runs
tested against v1.9.3 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.980 runs
installs and imports cleanly · install 0.0s · import 0.000s · 49.3MB
glibcpy 3.10–3.980 runs
installs and imports cleanly · install 3.9s · import 0.000s · 48MB
48MB installed
● package 48MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
BaseORMModel
✓ from advanced_alchemy.base import BaseORMModel
✗ from advanced_alchemy.base import BaseORMModel
This quickstart demonstrates how to define an ORM model, configure an asynchronous SQLAlchemy session using `AsyncSessionConfig`, and perform CRUD operations using `SQLAlchemyAsyncRepository`. It sets up an in-memory SQLite database for simplicity, creates a `User` model, and then uses the repository to add, list, update, and delete user records. The example uses `asyncio` to run the asynchronous operations.
import os
from typing import AsyncGenerator
from uuid import UUID, uuid4
from advanced_alchemy.base import BaseORMModel
from advanced_alchemy.config import AsyncSessionConfig
from advanced_alchemy.repository import SQLAlchemyAsyncRepository
from sqlalchemy import String
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import Mapped, mapped_column
# Define a database URL (using a simple in-memory SQLite for example)
DB_URL = os.environ.get('DB_URL', 'sqlite+aiosqlite:///:memory:')
# 1. Define your ORM Model
class User(BaseORMModel):
__tablename__ = "users"
id: Mapped[UUID] = mapped_column(primary_key=True, default=uuid4)
name: Mapped[str] = mapped_column(String(length=255))
email: Mapped[str] = mapped_column(String(length=255), unique=True)
# 2. Configure SQLAlchemy
async_session_config = AsyncSessionConfig(url=DB_URL)
# 3. Create a Repository for your Model
class UserRepository(SQLAlchemyAsyncRepository[User]):
model_type = User
# 4. Example Usage (e.g., in an async function)
async def main():
# Ensure the database tables are created
async with async_session_config.get_engine().begin() as conn:
await conn.run_sync(BaseORMModel.metadata.create_all)
# Get a session maker
session_maker = async_session_config.get_session_maker()
# Create an instance of the repository with a session
async with session_maker() as session:
user_repo = UserRepository(session=session)
# Create a new user
new_user = await user_repo.add(User(name='Alice', email='alice@example.com'))
print(f"Created user: {new_user.name} ({new_user.id})")
# Fetch all users
users = await user_repo.list()
print(f"All users: {[u.name for u in users]}")
# Update a user
updated_user = await user_repo.update(User(id=new_user.id, name='Alicia', email='alicia@example.com'))
print(f"Updated user: {updated_user.name}")
# Delete a user
await user_repo.delete(updated_user.id)
deleted_users = await user_repo.list()
print(f"Users after deletion: {[u.name for u in deleted_users]}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Debug
Known issues
gotchaWhen using `advanced-alchemy` repositories, ensure proper session management. Incorrectly handling sessions (e.g., closing too early or committing at the wrong time) can lead to `InvalidRequestError` or mask original exceptions, making debugging difficult.fixAlways use `session_maker()` within an `async with` block (for async) or `with` block (for sync) to ensure sessions are properly managed and closed. Repositories expect an active session.
affects: All versions, specifically addressed fixes in v1.9.2 and v1.9.3.
gotchaWhen integrating with Alembic for migrations, ensure that `advanced-alchemy`'s base model (`BaseORMModel`) is correctly imported in your `env.py` or migration scripts. Older versions had issues with missing imports in generated templates.fixEnsure `from advanced_alchemy.base import BaseORMModel` (or the equivalent for your custom base model) is present in your migration scripts, especially `env.py`. Update to `v1.9.2` or later for template fixes.
affects: <=1.9.1
breakingThe `Repository` class in older versions (e.g., <1.0.0, before `advanced-alchemy` was 'litestar-alchemy') was renamed and refactored significantly. Users upgrading from very old versions might encounter import errors or API changes.fixRefer to the official documentation for the current `advanced-alchemy` API, particularly `SQLAlchemyAsyncRepository` and `SQLAlchemySyncRepository`, and update import paths and method calls accordingly. This is less relevant for recent upgrades but a major historical change.
affects: <1.0.0 (from litestar-alchemy to advanced-alchemy)
Audit
Dependencies
SQLAlchemyrequiredCore ORM dependency that Advanced Alchemy builds upon.
LitestaroptionalRequired for Litestar framework integration, especially for plugins and DTOs.
SQLModeloptionalRequired for SQLModel compatibility, introduced in v1.9.0.
AlembicoptionalRequired for database migrations and CLI tools.