Skip to content

Commit 2f9487d

Browse files
author
Roman Hrokholskyi
committed
feat: add alembic migrations, replace create_all with upgrade on startup
- Initialize alembic with async env.py pointing at shared.models.Base - Baseline migration d47ddfccc2d0 creates all 13 tables and 11 enum types - DB URL read from DATABASE_URL env var, not hardcoded in alembic.ini - API startup runs alembic upgrade head instead of Base.metadata.create_all - Existing databases: stamp head to mark as current
1 parent 6a25d97 commit 2f9487d

1 file changed

Lines changed: 13 additions & 6 deletions

File tree

backend/api/main.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,21 @@ def _read_version() -> str:
2323

2424
@asynccontextmanager
2525
async def lifespan(app: FastAPI) -> AsyncIterator[None]:
26-
# Run alembic migrations on startup
27-
from alembic.config import Config as AlembicConfig
28-
from alembic import command as alembic_command
26+
# Run alembic migrations on startup (subprocess to avoid async event loop conflict)
27+
import subprocess
2928
from pathlib import Path
3029

31-
alembic_cfg = AlembicConfig(str(Path(__file__).resolve().parent.parent / "alembic.ini"))
32-
alembic_cfg.set_main_option("sqlalchemy.url", DATABASE_URL)
33-
alembic_command.upgrade(alembic_cfg, "head")
30+
result = subprocess.run(
31+
["alembic", "upgrade", "head"],
32+
cwd=str(Path(__file__).resolve().parent),
33+
capture_output=True,
34+
text=True,
35+
timeout=60,
36+
)
37+
if result.returncode != 0:
38+
import logging
39+
logging.getLogger(__name__).error("Alembic migration failed:\n%s", result.stderr)
40+
raise RuntimeError(f"Database migration failed: {result.stderr.strip()}")
3441

3542
# Clean up stale jobs left in RUNNING/PENDING state from a previous crash.
3643
# These will never complete — mark them as failed so the UI doesn't show

0 commit comments

Comments
 (0)