"""Alembic migration environment configuration for async SQLAlchemy.""" import asyncio import sys from logging.config import fileConfig from pathlib import Path from alembic import context from sqlalchemy import pool from sqlalchemy.ext.asyncio import async_engine_from_config # Add parent directory to path for imports sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from backend.app.core.config import settings # noqa: E402 from backend.app.db.base import Base # noqa: E402 # Import all models for autogenerate to discover them from backend.app.db.models import build # noqa: E402, F401 # Alembic Config object config = context.config # Set sqlalchemy.url from application settings config.set_main_option("sqlalchemy.url", settings.database_url) # Interpret the config file for Python logging if config.config_file_name is not None: fileConfig(config.config_file_name) # SQLAlchemy metadata for autogenerate support target_metadata = Base.metadata def run_migrations_offline() -> None: """Run migrations in 'offline' mode. This configures the context with just a URL and not an Engine, skipping Engine creation so no DBAPI is needed. """ url = config.get_main_option("sqlalchemy.url") context.configure( url=url, target_metadata=target_metadata, literal_binds=True, dialect_opts={"paramstyle": "named"}, ) with context.begin_transaction(): context.run_migrations() def do_run_migrations(connection) -> None: """Run migrations with the given connection.""" context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): context.run_migrations() async def run_migrations_online() -> None: """Run migrations in 'online' mode with async engine. Creates an async Engine and associates a connection with the context. """ connectable = async_engine_from_config( config.get_section(config.config_ini_section, {}), prefix="sqlalchemy.", poolclass=pool.NullPool, ) async with connectable.connect() as connection: await connection.run_sync(do_run_migrations) await connectable.dispose() if context.is_offline_mode(): run_migrations_offline() else: asyncio.run(run_migrations_online())