SQLAlchemy Migrations with Alembic (Production Setup)
Introduction
In real-world applications, your database schema evolves over time:
- Add new columns
- Modify tables
- Remove fields
Instead of manually writing SQL each time, we use Alembic the official migration tool for SQLAlchemy.
What is Alembic?
Alembic is a database migration tool that:
- Tracks schema changes
- Generates migration scripts
- Applies updates safely
Why Use Alembic?
- Version control for database schema
- Safe updates (no data loss if used correctly)
- Works with all SQLAlchemy-supported DBs
- Essential for production apps
Step 1: Install Alembic
pip install alembic
Step 2: Initialize Alembic
alembic init alembic
This creates:
alembic/versions/env.pyalembic.ini
Project Structure
project/│├── models.py├── database.py├── alembic/├── alembic.iniStep 3: Configure Database Connection
Open alembic.ini:
sqlalchemy.url = sqlite:///example.dbConnect Models in env.py
Edit
alembic/env.py:from models import Basetarget_metadata = Base.metadataThis allows Alembic to detect model changes automatically.
Step 4: Create First Migration
alembic revision --autogenerate -m "create users table"
Example Migration File
def upgrade():op.create_table('users',sa.Column('id', sa.Integer(), primary_key=True),sa.Column('name', sa.String()),)def downgrade():op.drop_table('users')
Step 5: Apply Migration
alembic upgrade head
This updates your database schema.
Step 6: Modify Models & Migrate Again
Example: Add Email Column
email = Column(String)Generate Migration
alembic revision --autogenerate -m "add email column"Apply Changes
alembic upgrade headRollback
Downgrade One Step
alembic downgrade -1Downgrade to Specific Version
alembic downgrade <revision_id>Advanced Alembic Features
1. Rename Column
op.alter_column('users', 'name', new_column_name='full_name')2. Add Column
op.add_column('users', sa.Column('age', sa.Integer()))3. Drop Column
op.drop_column('users', 'age')4. Create Index
op.create_index('idx_user_name', 'users', ['name'])
Handling Data Migration
Sometimes you need to modify data, not just schema.
op.execute("UPDATE users SET name='Unknown' WHERE name IS NULL")
Real-World Workflow
- Update models.py
- Generate migration
- Review migration file
- Apply migration
- Deploy
Handling Data Migration
Sometimes you need to modify data, not just schema.
op.execute("UPDATE users SET name='Unknown' WHERE name IS NULL")
Real-World Workflow
- Update models.py
- Generate migration
- Review migration file
- Apply migration
- Deploy
Common Mistakes
- Blindly running
--autogeneratewithout checking - Not backing up production database
- Editing DB manually (breaks migration history)
- Forgetting downgrade logic
Production Best Practices
- Always review migration scripts
- Use version control (Git)
- Test migrations in staging
- Backup DB before applying
- Keep migrations small and clear
Alembic with FastAPI
# database.pyfrom sqlalchemy import create_enginefrom sqlalchemy.orm import sessionmakerengine = create_engine(DATABASE_URL)SessionLocal = sessionmaker(bind=engine)
Alembic uses the same database URL.
- Alembic manages schema changes safely
- Autogenerate saves time
- Upgrade & downgrade control versions
- Essential for production-ready apps
Comments
Post a Comment