Migrations¶
SAE Books uses Alembic for schema migrations. Migration files live
in alembic/versions/ and follow the convention
NNNN_short_slug.py where NNNN is a 4-digit zero-padded sequence
(e.g. 0170_ephemeral_demo_tenants.py).
Tip
Migration IDs go up monotonically across all branches. Don't
reuse a number — if you cherry-pick a migration into a different
chain, renumber to the next free slot. Alembic will reject a
duplicate revision ID at runtime, but the friendly fix is to
avoid the collision in the first place.
Adding a migration¶
The Makefile revision target wraps alembic revision:
For an autogenerated diff from your model changes, run the command directly:
Review the generated diff carefully — Alembic autogen handles columns and indexes well but has known blind spots (server defaults, check constraints, enum types). Hand-edit where needed.
Applying¶
# Via Makefile (recommended during development)
make migrate
# Or directly
docker compose exec app alembic upgrade head
Rollback¶
downgrade -1 walks back one revision. Be cautious in prod —
downgrades that drop columns or tables are destructive.
Production deploys¶
entrypoint.sh runs alembic upgrade head before starting uvicorn on
every container start. If a migration fails, the container exits
non-zero and the orchestrator restarts it. To force a manual run, exec
into a healthy container and run alembic upgrade head interactively,
then restart the container.
Warning
Migration 0128_app_role reads SAEBOOKS_APP_DB_PASSWORD from the
environment. This variable must be set in the compose .env
before running migrations on a fresh database; the migration refuses
to apply if the variable is absent or empty.