Files

94 lines
2.4 KiB
Python

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()