Alembic is the database migration tool created by Mike Bayer, the same person who gave us SQLAlchemy. Running the latest version and it works fine with SQLAlchemy 2.0.
Django devs have it easy - migrations are built in. The rest of us had to cobble together schema change scripts until Alembic came along in 2010. Now it's the de facto standard for Python database migrations outside Django.
The Problem It Solves
Ever deployed code and realized your new feature needs a database column that doesn't exist in prod? Or worse, tried to manually run ALTER TABLE statements on production and accidentally broke everything? Yeah, we've all been there.
Database schemas change constantly during development, but unlike your code changes, there's no git for your database structure. Until Alembic.
What It Actually Does
Tracks Database Changes: Alembic creates migration files that describe exactly what changed in your database schema. Each migration tracks what changed, just like git commits but for your database. Each migration has a unique UUID and knows which migration comes before and after it.
Handles the Scary Database Stuff: PostgreSQL is smart enough to support transactional DDL, so migrations run inside transactions. If your migration shits the bed halfway through, PostgreSQL rolls it all back automatically. No more manually cleaning up half-applied schema changes at 2 AM.
Autogenerates (Most) Migrations: Run alembic revision --autogenerate
and it compares your SQLAlchemy models to your actual database, then generates a migration script. It catches maybe 80% of changes automatically - table creation, column additions, basic type changes. The other 20% you'll need to fix by hand, but that beats writing everything from scratch.
Why It's Better Than Alternatives
Actually Works With SQLAlchemy: Unlike generic migration tools that don't understand your ORM, Alembic gets SQLAlchemy's type system, relationships, and constraints. It knows the difference between PostgreSQL's UUID type and MySQL's CHAR(36).
Handles Branching: Multiple developers working on different features? Alembic's branching system lets you merge database changes like you merge code. No more "migration already exists" conflicts.
SQLite Doesn't Suck: SQLite's ALTER TABLE support is trash - you can't drop columns, rename them, or do much of anything. Alembic's batch migration mode works around this by recreating tables behind the scenes.
DBAs Don't Hate You: Generate SQL scripts instead of running migrations directly with --sql
flag. Your DBA can review the actual SQL before it touches production.
When Alembic Will Ruin Your Day
Autogenerate is Drunk: It can't detect column renames (drops old, creates new = bye data), index renames, or complex constraint changes. I learned this the hard way when it generated DROP COLUMN user_name; ADD COLUMN username
and wiped like 50k user records - maybe more? - because I was an idiot and didn't review what it generated. Always review what it generates - I can't stress this enough.
SQLite Edge Cases: Batch migrations work great until you have foreign keys pointing to the table you're modifying. Then you're debugging for hours.
Data Migrations: Alembic handles schema changes, not data changes. Need to populate that new column? Write the data migration yourself in the same script.
The Bottom Line
If you're using SQLAlchemy, use Alembic. It's not perfect, but it's the best tool for keeping database schema changes synchronized across development, staging, and production without losing your sanity or your data. Read the official tutorial to get started properly.