"""Alembic environment — async, schema-isolated to the ClassLens schema. The DB connection and target schema come from application settings, so the same migrations run against Supabase (schema=classlens) or local SQLite (schema=None). Only the ClassLens schema is ever touched — other apps sharing the DB are ignored. """ from __future__ import annotations import asyncio from logging.config import fileConfig from alembic import context from app.db import active_schema, get_engine from app.models import Base # noqa: F401 (registers all tables on Base.metadata) config = context.config if config.config_file_name: fileConfig(config.config_file_name) target_metadata = Base.metadata SCHEMA = active_schema() def _include_object(obj, name, type_, reflected, compare_to): """Never let autogenerate manage tables outside our schema.""" if type_ == "table": return getattr(obj, "schema", None) == SCHEMA return True def _configure(connection): context.configure( connection=connection, target_metadata=target_metadata, version_table_schema=SCHEMA, include_schemas=False, include_object=_include_object, compare_type=True, ) def _run(connection): _configure(connection) with context.begin_transaction(): context.run_migrations() async def run_async(): engine = get_engine() async with engine.connect() as conn: await conn.run_sync(_run) await engine.dispose() if context.is_offline_mode(): context.configure( url=str(get_engine().url), target_metadata=target_metadata, version_table_schema=SCHEMA, include_object=_include_object, literal_binds=True, dialect_opts={"paramstyle": "named"}, ) with context.begin_transaction(): context.run_migrations() else: asyncio.run(run_async())