from __future__ import annotations import asyncio from logging.config import fileConfig from typing import Any from alembic import context from common.config import settings from common.db.models.operations import OperationsBase from sqlalchemy import Connection, pool from sqlalchemy.ext.asyncio import async_engine_from_config config = context.config if config.config_file_name is not None: fileConfig(config.config_file_name) target_metadata = OperationsBase.metadata def database_url() -> str: value = settings.operations_database_url if not value: raise RuntimeError("OPERATIONS_DATABASE_URL is required") return value def include_object( obj: Any, name: str | None, type_: str, reflected: bool, compare_to: Any, ) -> bool: """Protect audited ops tables not yet represented in the P0 ORM subset.""" if type_ == "table" and reflected and compare_to is None: return False return type_ != "table" or bool(name and name.startswith("ops_")) def configure_context(*, connection: Connection | None = None) -> None: options = { "target_metadata": target_metadata, "compare_type": True, "compare_server_default": True, "include_object": include_object, } if connection is None: context.configure( url=database_url(), literal_binds=True, dialect_opts={"paramstyle": "named"}, **options, ) else: context.configure(connection=connection, **options) def run_migrations_offline() -> None: configure_context() with context.begin_transaction(): context.run_migrations() def do_run_migrations(connection: Connection) -> None: configure_context(connection=connection) with context.begin_transaction(): context.run_migrations() async def run_async_migrations() -> None: section = config.get_section(config.config_ini_section, {}) section["sqlalchemy.url"] = database_url() connectable = async_engine_from_config( section, prefix="sqlalchemy.", poolclass=pool.NullPool, ) try: async with connectable.connect() as connection: await connection.run_sync(do_run_migrations) finally: await connectable.dispose() def run_migrations_online() -> None: asyncio.run(run_async_migrations()) if context.is_offline_mode(): run_migrations_offline() else: run_migrations_online()