This directory contains Alembic database migrations for managing schema evolution.
We use Alembic for database migrations to:
- Track schema changes over time
- Enable safe schema evolution across environments
- Provide repeatable, testable database deployments
- Support both forward (upgrade) and backward (downgrade) migrations
alembic/
├── versions/ # Migration files (one per schema change)
├── env.py # Alembic environment configuration
├── script.py.mako # Template for new migration files
└── README # This file
Migration files are stored in versions/ and follow this naming pattern:
YYYYMMDD_HHMM_<revision_id>_<description>.py
Example: 20251024_1740_5cd038a8f131_initial_schema_baseline.py
Each migration file contains:
- Metadata: Revision ID, parent revision, creation date
- upgrade(): Function to apply schema changes
- downgrade(): Function to revert schema changes
The baseline migration (5cd038a8f131_initial_schema_baseline.py) captures the existing schema from sql/schema.sql. This serves as the foundation for all future migrations.
Simply run migrations on an empty database:
python scripts/run_migrations.py upgradeIf you have an existing database created from sql/schema.sql, stamp it at the baseline:
python scripts/run_migrations.py stamp headThis tells Alembic your database is already at the baseline, preventing it from trying to re-create existing tables.
For comprehensive migration examples and templates, see:
- Migration Template Guide - Detailed examples for all migration types
- Production Runbook - Production deployment procedures
- CONTRIBUTING.md - Development workflow
See the Database Migrations section in CONTRIBUTING.md for detailed guidelines on:
- Creating new migrations
- Testing migrations
- Best practices
- Common scenarios
- Example code
For production migration procedures, see:
- Production Migration Runbook
- Pre-migration checklist
- Step-by-step execution
- Rollback procedures
- Zero-downtime patterns
- Blue-green deployment
- Performance considerations
Migrations are automatically validated in CI via .github/workflows/migrations-ci.yml:
- Fresh database test (empty → fully migrated)
- Existing schema test (stamp → no-op upgrade)
- Up/down test (upgrade → downgrade → upgrade)
All tests must pass before changes can be merged.
When running with Docker Compose, migrations are automatically applied on startup:
docker compose up -dThe migrations service runs python scripts/run_migrations.py upgrade before the API and worker services start.
python scripts/run_migrations.py currentpython scripts/run_migrations.py historypython scripts/run_migrations.py upgradepython scripts/run_migrations.py downgradealembic revision -m "descriptive_name"- Never modify existing migrations once they're committed and deployed
- Always test both upgrade and downgrade before committing
- Keep migrations atomic - one logical change per migration
- Document complex migrations with comments
- Consider data safety - migrations can delete data if not careful
- Test with production-like data when possible
Your database may have been created from sql/schema.sql. Stamp it:
python scripts/run_migrations.py stamp headThe alembic_version table may be out of sync. Check current revision:
python scripts/run_migrations.py currentIf multiple people create migrations simultaneously, you may need to merge them:
- Rebase your branch
- Update the
down_revisionin your migration to point to the latest - Test the migration sequence