task-queue-system/migrations/env.py
2025-12-11 16:54:45 +01:00

104 lines
4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# migrations/env.py
from __future__ import annotations
import asyncio
import os
import sys
from logging.config import fileConfig
from alembic import context
from sqlalchemy import pool
from sqlalchemy.engine import Connection
from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine
# ----------------------------------------------------------------------
# Alembic Grund-Setup (Logging etc.)
# ----------------------------------------------------------------------
config = context.config
if config.config_file_name is not None:
fileConfig(config.config_file_name)
# ----------------------------------------------------------------------
# Projekt-Root auf sys.path, damit "from app ..." klappt
# ----------------------------------------------------------------------
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
if ROOT not in sys.path:
sys.path.insert(0, ROOT)
# ----------------------------------------------------------------------
# ORM-Base & Modelle importieren (wichtig: Modelle registrieren Tabellen)
# ----------------------------------------------------------------------
from app.db import Base
from app import models # noqa: F401
target_metadata = Base.metadata
# ----------------------------------------------------------------------
# Async-DB-URL (z. B. postgresql+asyncpg://...)
# ----------------------------------------------------------------------
DATABASE_URL = os.getenv("DATABASE_URL")
if not DATABASE_URL:
raise RuntimeError(
"DATABASE_URL ist nicht gesetzt (z. B. postgresql+asyncpg://user:pass@host:5432/db)"
)
# ----------------------------------------------------------------------
# (Optional) Leere Autogenerate-Revisionen unterdrücken
# ----------------------------------------------------------------------
def process_revision_directives(context, revision, directives):
cmd_opts = getattr(config, "cmd_opts", None)
if cmd_opts and getattr(cmd_opts, "autogenerate", False):
script = directives[0]
if hasattr(script, "upgrade_ops") and script.upgrade_ops.is_empty():
directives[:] = [] # keine 'pass'-Revision erzeugen
# ----------------------------------------------------------------------
# Offline-Pfad (bewusst deaktiviert, damit Autogenerate immer online läuft)
# ----------------------------------------------------------------------
def run_migrations_offline() -> None:
raise RuntimeError("Offline-Modus deaktiviert bitte Online-Modus verwenden.")
# ----------------------------------------------------------------------
# Online-Pfad (AsyncEngine + run_sync)
# ----------------------------------------------------------------------
async def run_migrations_online() -> None:
connectable: AsyncEngine = create_async_engine(
DATABASE_URL,
poolclass=pool.NullPool,
future=True,
)
async with connectable.connect() as async_conn:
def do_run_migrations(connection: Connection) -> None:
# WICHTIG: connection + target_metadata -> nötige Voraussetzung
# damit Alembic den DB-Ist gegen ORM-Soll vergleicht (Autogenerate)
context.configure(
connection=connection,
target_metadata=target_metadata,
compare_type=True,
compare_server_default=True,
include_schemas=True,
process_revision_directives=process_revision_directives,
)
with context.begin_transaction():
context.run_migrations()
# run_sync ruft do_run_migrations(connection) auf
await async_conn.run_sync(do_run_migrations)
await connectable.dispose()
# ----------------------------------------------------------------------
# WICHTIG: beim Import starten KEIN __main__-Guard
# ----------------------------------------------------------------------
def run_migrations() -> None:
if context.is_offline_mode():
run_migrations_offline()
else:
asyncio.run(run_migrations_online())
run_migrations()