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
- Pull latest code
- Run
flask db upgradeto apply any new migrations - Make your model changes
- Run
flask db migrate -m "Description" - Review the generated migration
- Test with
flask db upgrade - 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:
- Merge the migration files carefully
- Update the
down_revisionin the newer migration - Test thoroughly
Best Practices
- One migration per feature - Don't bundle unrelated changes
- Descriptive messages - Use clear migration messages
- Review before applying - Always check generated SQL
- Test rollbacks - Ensure downgrade() works
- 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 managementmigrate_to_alembic.py- One-time transition from old systeminit_migrations.py- Quick initialization script
Environment Variables
# Required for migrations
export FLASK_APP=app.py
export DATABASE_URL=postgresql://user:pass@host/db