Files
membership-be/alembic
2026-01-05 02:28:47 +07:00
..
2026-01-04 19:08:54 +07:00
2026-01-04 19:08:54 +07:00
2026-01-04 19:08:54 +07:00
2026-01-04 19:08:54 +07:00

Alembic Database Migrations

This directory contains Alembic database migrations for the LOAF membership platform.

What is Alembic?

Alembic is a lightweight database migration tool for SQLAlchemy. It allows you to:

  • Track database schema changes over time
  • Apply migrations incrementally
  • Roll back changes if needed
  • Auto-generate migration scripts from model changes

Directory Structure

alembic/
├── versions/          # Migration scripts (KEEP IN VERSION CONTROL)
│   └── *.py          # Individual migration files
├── env.py            # Alembic environment configuration
├── script.py.mako    # Template for new migration files
└── README.md         # This file

Quick Start

1. Create a New Migration

After making changes to models.py, generate a migration:

cd backend
alembic revision --autogenerate -m "add_user_bio_field"

This will create a new file in alembic/versions/ like:

3e02c74581c9_add_user_bio_field.py

2. Review the Generated Migration

IMPORTANT: Always review auto-generated migrations before applying them!

# Open the latest migration file
cat alembic/versions/3e02c74581c9_add_user_bio_field.py

Check:

  • The upgrade() function contains the correct changes
  • The downgrade() function properly reverses those changes
  • No unintended table drops or data loss

3. Apply the Migration

# Apply all pending migrations
alembic upgrade head

# Or apply migrations one at a time
alembic upgrade +1

4. Rollback a Migration

# Rollback the last migration
alembic downgrade -1

# Rollback to a specific revision
alembic downgrade 3e02c74581c9

Common Commands

Command Description
alembic current Show current migration revision
alembic history Show migration history
alembic heads Show head revisions
alembic upgrade head Apply all pending migrations
alembic downgrade -1 Rollback last migration
alembic revision --autogenerate -m "message" Create new migration
alembic stamp head Mark database as up-to-date without running migrations

Migration Workflow

For Development

  1. Make changes to models.py

    # In models.py
    class User(Base):
        # ...existing fields...
        bio = Column(Text, nullable=True)  # New field
    
  2. Generate migration

    alembic revision --autogenerate -m "add_user_bio_field"
    
  3. Review the generated file

    # In alembic/versions/xxxxx_add_user_bio_field.py
    def upgrade():
        op.add_column('users', sa.Column('bio', sa.Text(), nullable=True))
    
    def downgrade():
        op.drop_column('users', 'bio')
    
  4. Apply migration

    alembic upgrade head
    
  5. Commit migration file to Git

    git add alembic/versions/xxxxx_add_user_bio_field.py
    git commit -m "Add user bio field"
    

For Production Deployment

Fresh Database (New Installation):

# 1. Create database
createdb membership_db

# 2. Run initial schema SQL (creates all 17 tables)
psql -U username -d membership_db -f ../migrations/000_initial_schema.sql

# 3. Mark database as up-to-date with Alembic
alembic stamp head

# 4. Verify
alembic current  # Should show: 001_initial_baseline (head)

Existing Database (Apply New Migrations):

# 1. Pull latest code
git pull origin main

# 2. Apply migrations
alembic upgrade head

# 3. Verify
alembic current

# 4. Restart application
systemctl restart membership-backend

Configuration

Database Connection

Alembic reads the DATABASE_URL from your .env file:

DATABASE_URL=postgresql://user:password@localhost:5432/membership_db

The connection is configured in alembic/env.py (lines 29-36).

Target Metadata

Alembic uses Base.metadata from models.py to detect changes:

# In alembic/env.py
from models import Base
target_metadata = Base.metadata

Important Notes

DO:

  • Always review auto-generated migrations before applying
  • Test migrations in development before production
  • Commit migration files to version control
  • Write descriptive migration messages
  • Include both upgrade() and downgrade() functions

DON'T:

  • Don't edit migration files after they've been applied in production
  • Don't delete migration files from alembic/versions/
  • Don't modify the revision or down_revision values
  • Don't commit .pyc files (already in .gitignore)

Migration History

Revision Description Date Type
001_initial_baseline Baseline marker (empty migration) 2026-01-02 Baseline

Note: The actual initial schema is created by running backend/migrations/000_initial_schema.sql. The baseline migration is an empty marker that indicates the starting point for Alembic tracking.

Troubleshooting

"Target database is not up to date"

# Check current revision
alembic current

# Check pending migrations
alembic history

# Apply missing migrations
alembic upgrade head

"FAILED: Can't locate revision identified by 'xxxxx'"

The database thinks it's at a revision that doesn't exist in your alembic/versions/.

Solution:

# Mark database at a known good revision
alembic stamp head

Migration conflicts

If you get merge conflicts in migration files:

  1. Resolve conflicts in the migration file
  2. Ensure revision and down_revision chain is correct
  3. Test the migration locally

Fresh database setup

For a completely new database:

# Step 1: Run initial schema SQL
psql -U username -d membership_db -f ../migrations/000_initial_schema.sql

# Step 2: Mark as up-to-date
alembic stamp head

# Step 3: Verify
alembic current  # Should show: 001_initial_baseline (head)

Legacy Migrations

Old numbered SQL migrations (000_initial_schema.sql through 011_wordpress_import_enhancements.sql) are preserved in backend/migrations/ for reference. These have been consolidated into the initial Alembic migration.

Going forward, all new migrations must use Alembic.

Additional Resources