lesson depth
Mastery
not started · 0%

Schema Migrations with Alembic

Database revision histories, auto-generation DDL scripts, lock timeout safety, and zero-downtime migrations.

Freshness: current15 min readData Engineering and Databases

Key Learning Outcomes

  • Write non-blocking Alembic migration scripts
  • Execute zero-downtime schema migrations in CI/CD

Mental model

Alembic provides a version-controlled database migration framework for SQLAlchemy, tracking schema revisions in a dedicated alembic_version table.

Inspect SQLAlchemy Model Metadata
Auto-generate Migration Script (alembic revision)
Apply Lock Timeout Safety Guards
Execute DDL inside Migration Transaction
Update alembic_version revision table
Conceptual teaching model synthesized from:FastAPI Framework Architecture & Dependency Injection Specification

Theory

Production DDL statements (ALTER TABLE, ADD COLUMN) acquire table locks. If a migration waits for an exclusive lock behind long-running queries, subsequent SELECT queries queue up behind it, exhausting connection pools. Safe migrations configure strict lock_timeout values prior to DDL execution.

python(19 lines)
1# Alembic env.py - Adding lock timeout safety
2from alembic import context
3from sqlalchemy import engine_from_config, pool
4
5def run_migrations_online():
6 connectable = context.get_engine()
7 with connectable.connect() as connection:
8 # Prevent DDL migrations from locking tables indefinitely
9 connection.execute("SET lock_timeout = '5s';")
10 connection.execute("SET statement_timeout = '60s';")
11
12 context.configure(
13 connection=connection,
14 target_metadata=target_metadata,
15 compare_type=True
16 )
17 with context.begin_transaction():
18 context.run_migrations()

Alternatives and trade-offs

  • Manual DDL SQL Scripts: Error-prone, hard to track in CI/CD, no automated rollback verification.
  • Alembic Versioned Migrations: Audited, repeatable, auto-generates delta scripts from SQLAlchemy model changes.

Failure modes and misconceptions

  1. Blocking Default Values: Adding a column with a non-constant default (ALTER TABLE users ADD COLUMN created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL) in PostgreSQL < 11 rewrote the entire table, holding an ACCESS EXCLUSIVE lock.
  2. Dropping Columns in Single Deployment: Dropping a column while old application pods are still running causes HTTP 500 crashes. Always use multi-phase expand/contract migrations.
Reflect before revealing the guide

Decision scenario

Configure SET lock_timeout = '5s' in Alembic env.py so that production schema migration deployment scripts fail fast rather than blocking user queries if a lock cannot be acquired immediately.

Learning outcomes

  • Structure version-controlled database migrations using Alembic.
  • Enforce lock timeout safety to prevent DDL migration deadlocks.
  • Execute zero-downtime expand/contract schema migrations.

Trade-offs

Alembic automates database schema evolution, but auto-generated revision scripts must be manually audited before applying DDL changes in production.

Prerequisites & Related Concepts (2)

Private notes

0 words
Next