{"id":6953,"library":"advanced-alchemy","title":"Advanced Alchemy","description":"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.","status":"active","version":"1.9.3","language":"en","source_language":"en","source_url":"https://github.com/litestar-org/advanced-alchemy","tags":["SQLAlchemy","ORM","database","repository pattern","Litestar","async","migrations"],"install":[{"cmd":"pip install advanced-alchemy","lang":"bash","label":"Install core library"},{"cmd":"pip install advanced-alchemy[sqlmodel]","lang":"bash","label":"Install with SQLModel support"},{"cmd":"pip install advanced-alchemy[litestar]","lang":"bash","label":"Install with Litestar integration"},{"cmd":"pip install advanced-alchemy[alembic]","lang":"bash","label":"Install with Alembic support"}],"dependencies":[{"reason":"Core ORM dependency that Advanced Alchemy builds upon.","package":"SQLAlchemy"},{"reason":"Required for Litestar framework integration, especially for plugins and DTOs.","package":"Litestar","optional":true},{"reason":"Required for SQLModel compatibility, introduced in v1.9.0.","package":"SQLModel","optional":true},{"reason":"Required for database migrations and CLI tools.","package":"Alembic","optional":true}],"imports":[{"symbol":"BaseORMModel","correct":"from advanced_alchemy.base import BaseORMModel"},{"symbol":"SQLAlchemyAsyncRepository","correct":"from advanced_alchemy.repository import SQLAlchemyAsyncRepository"},{"symbol":"SQLAlchemySyncRepository","correct":"from advanced_alchemy.repository import SQLAlchemySyncRepository"},{"symbol":"SQLAlchemyLitestarConfig","correct":"from advanced_alchemy.config import SQLAlchemyLitestarConfig"},{"symbol":"SQLAlchemyPlugin","correct":"from advanced_alchemy.extensions.litestar.plugins import SQLAlchemyPlugin"}],"quickstart":{"code":"import os\nfrom typing import AsyncGenerator\nfrom uuid import UUID, uuid4\n\nfrom advanced_alchemy.base import BaseORMModel\nfrom advanced_alchemy.config import AsyncSessionConfig\nfrom advanced_alchemy.repository import SQLAlchemyAsyncRepository\nfrom sqlalchemy import String\nfrom sqlalchemy.ext.asyncio import AsyncSession\nfrom sqlalchemy.orm import Mapped, mapped_column\n\n# Define a database URL (using a simple in-memory SQLite for example)\nDB_URL = os.environ.get('DB_URL', 'sqlite+aiosqlite:///:memory:')\n\n# 1. Define your ORM Model\nclass User(BaseORMModel):\n    __tablename__ = \"users\"\n\n    id: Mapped[UUID] = mapped_column(primary_key=True, default=uuid4)\n    name: Mapped[str] = mapped_column(String(length=255))\n    email: Mapped[str] = mapped_column(String(length=255), unique=True)\n\n# 2. Configure SQLAlchemy\nasync_session_config = AsyncSessionConfig(url=DB_URL)\n\n# 3. Create a Repository for your Model\nclass UserRepository(SQLAlchemyAsyncRepository[User]):\n    model_type = User\n\n# 4. Example Usage (e.g., in an async function)\nasync def main():\n    # Ensure the database tables are created\n    async with async_session_config.get_engine().begin() as conn:\n        await conn.run_sync(BaseORMModel.metadata.create_all)\n\n    # Get a session maker\n    session_maker = async_session_config.get_session_maker()\n\n    # Create an instance of the repository with a session\n    async with session_maker() as session:\n        user_repo = UserRepository(session=session)\n\n        # Create a new user\n        new_user = await user_repo.add(User(name='Alice', email='alice@example.com'))\n        print(f\"Created user: {new_user.name} ({new_user.id})\")\n\n        # Fetch all users\n        users = await user_repo.list()\n        print(f\"All users: {[u.name for u in users]}\")\n\n        # Update a user\n        updated_user = await user_repo.update(User(id=new_user.id, name='Alicia', email='alicia@example.com'))\n        print(f\"Updated user: {updated_user.name}\")\n\n        # Delete a user\n        await user_repo.delete(updated_user.id)\n        deleted_users = await user_repo.list()\n        print(f\"Users after deletion: {[u.name for u in deleted_users]}\")\n\nif __name__ == \"__main__\":\n    import asyncio\n    asyncio.run(main())\n","lang":"python","description":"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."},"warnings":[{"fix":"Always 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.","message":"When 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.","severity":"gotcha","affected_versions":"All versions, specifically addressed fixes in v1.9.2 and v1.9.3."},{"fix":"Ensure `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.","message":"When 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.","severity":"gotcha","affected_versions":"<=1.9.1"},{"fix":"Refer 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.","message":"The `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.","severity":"breaking","affected_versions":"<1.0.0 (from litestar-alchemy to advanced-alchemy)"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure your session is managed correctly, typically using `async with session_maker() as session:` for asynchronous operations. Pass an active session to your repository instance.","cause":"Attempting to use a SQLAlchemy session that has already been committed, rolled back, or is in an invalid state, often due to improper `session.close()` or `session.commit()` calls.","error":"sqlalchemy.exc.InvalidRequestError: This session is in 'pending' state, and no further operations are allowed."},{"fix":"Upgrade `advanced-alchemy` to version `1.9.2` or later, as this specific import issue was fixed in `v1.9.1` for migration templates. If manually creating templates, ensure correct import paths.","cause":"This specific error often indicates an issue with `advanced-alchemy`'s Alembic integration or templating, where it might incorrectly reference or generate templates. This was a known bug.","error":"ModuleNotFoundError: No module named 'alembic.templates.sync'"},{"fix":"Before adding or updating, check for the existence of the record with the unique key. Wrap `repository.add()` or `repository.update()` calls in a `try...except IntegrityError` block to handle the specific violation gracefully.","cause":"Attempting to insert a record with a unique constraint violation (e.g., duplicate email address for a unique column) when using a repository `add` or `update` method.","error":"sqlalchemy.exc.IntegrityError: (psycopg2.errors.UniqueViolation) duplicate key value violates unique constraint"}]}