Files
TimeTrack/FLASK_MIGRATE_GUIDE.md

5.4 KiB

Flask-Migrate Migration Guide

Overview

TimeTrack has been refactored to use Flask-Migrate (which wraps Alembic) for database migrations instead of manual SQL scripts. This provides automatic migration generation, version control, and rollback capabilities.

IMPORTANT: The baseline for Flask-Migrate is set at git commit 4214e88d18fce7a9c75927753b8d4e9222771e14. All schema changes after this commit need to be recreated as Flask-Migrate migrations.

For Docker Deployments: See DOCKER_MIGRATIONS_GUIDE.md for Docker-specific instructions (no Git required).

Migration from Old System

For Existing Deployments

If you have an existing database with the old migration system:

# 1. Install new dependencies
pip install -r requirements.txt

# 2. Establish baseline from commit 4214e88
python simple_baseline_4214e88.py
# Note: Use simple_baseline_4214e88.py as it handles the models.py transition correctly

# 3. Mark your database as being at the baseline
flask db stamp head

# 4. Apply any post-baseline migrations
# Review migrations_old/postgres_only_migration.py for changes after 4214e88
# Create new migrations for each feature:
flask db migrate -m "Add company updated_at column"
flask db migrate -m "Add user 2FA columns"
flask db migrate -m "Add company invitation table"
# etc...

For New Deployments

# 1. Install dependencies
pip install -r requirements.txt

# 2. Initialize and create database
python manage_migrations.py init
python manage_migrations.py apply

Daily Usage

Creating Migrations

When you modify models (add columns, tables, etc.):

# Generate migration automatically
flask db migrate -m "Add user avatar field"

# Or use the helper script
python manage_migrations.py create -m "Add user avatar field"

Always review the generated migration in migrations/versions/ before applying!

Applying Migrations

# Apply all pending migrations
flask db upgrade

# Or use the helper script
python manage_migrations.py apply

Rolling Back

# Rollback one migration
flask db downgrade

# Or use the helper script
python manage_migrations.py rollback

Viewing Status

# Current migration version
flask db current

# Migration history
flask db history

# Or use the helper script
python manage_migrations.py history

Important Considerations

1. PostgreSQL Enums

Flask-Migrate may not perfectly handle PostgreSQL enum types. When adding new enum values:

# In the migration file, you may need to add:
from alembic import op
import sqlalchemy as sa

def upgrade():
    # Add new enum value
    op.execute("ALTER TYPE taskstatus ADD VALUE 'NEW_STATUS'")

2. Data Migrations

For complex data transformations, add custom code to migration files:

def upgrade():
    # Schema changes
    op.add_column('user', sa.Column('new_field', sa.String()))
    
    # Data migration
    connection = op.get_bind()
    result = connection.execute('SELECT id, old_field FROM user')
    for row in result:
        connection.execute(
            f"UPDATE user SET new_field = '{process(row.old_field)}' WHERE id = {row.id}"
        )

3. Production Deployments

The startup scripts have been updated to automatically run migrations:

# startup_postgres.sh now includes:
flask db upgrade

4. Development Workflow

  1. Pull latest code
  2. Run flask db upgrade to apply any new migrations
  3. Make your model changes
  4. Run flask db migrate -m "Description"
  5. Review the generated migration
  6. Test with flask db upgrade
  7. Commit both model changes and migration file

Troubleshooting

"Target database is not up to date"

# Check current version
flask db current

# Force upgrade
flask db stamp head  # Mark as latest without running
flask db upgrade     # Apply any pending

"Can't locate revision"

Your database revision doesn't match any migration file. This happens when switching branches.

# See all migrations
flask db history

# Stamp to a specific revision
flask db stamp <revision_id>

Migration Conflicts

When multiple developers create migrations:

  1. Merge the migration files carefully
  2. Update the down_revision in the newer migration
  3. Test thoroughly

Best Practices

  1. One migration per feature - Don't bundle unrelated changes
  2. Descriptive messages - Use clear migration messages
  3. Review before applying - Always check generated SQL
  4. Test rollbacks - Ensure downgrade() works
  5. Backup before major migrations - Especially in production

Migration File Structure

migrations/
├── README.md          # Quick reference
├── alembic.ini       # Alembic configuration
├── env.py            # Migration environment
├── script.py.mako    # Migration template
└── versions/         # Migration files
    ├── 001_initial_migration.py
    ├── 002_add_user_avatars.py
    └── ...

Helper Scripts

  • manage_migrations.py - Simplified migration management
  • migrate_to_alembic.py - One-time transition from old system
  • init_migrations.py - Quick initialization script

Environment Variables

# Required for migrations
export FLASK_APP=app.py
export DATABASE_URL=postgresql://user:pass@host/db

References