# Complete Database Migration Guide This guide covers **ALL** possible migration scenarios from any previous database state to the new Flask-Migrate system. ## 🎯 Migration Scenarios Covered ### 1. **Fresh Installation** (No existing database) - New project setup - First-time deployment ### 2. **Existing Database with Old Custom Migrations** - Legacy migration scripts - Custom Python migration files - Manual schema changes ### 3. **Existing Database with Mixed Schema** - Some tables exist, some missing - Incomplete schema - Partial migrations ### 4. **Existing Database with Data** - Production databases with user data - Development databases with test data - Staging databases ### 5. **Database from Different Versions** - Old TimeTracker versions - Different schema versions - Incompatible table structures ## 🚀 Migration Methods ### **Method 1: Automated Migration (Recommended)** #### **For Any Existing Database:** ```bash # Run the comprehensive migration script python migrations/migrate_existing_database.py ``` This script will: - ✅ Detect your database type (PostgreSQL/SQLite) - ✅ Create a complete backup - ✅ Analyze existing schema - ✅ Create migration strategy - ✅ Initialize Flask-Migrate - ✅ Create baseline migration - ✅ Preserve all existing data - ✅ Verify migration success #### **For Legacy Schema Migration:** ```bash # Run the legacy schema migration script python migrations/legacy_schema_migration.py ``` This script handles: - ✅ Old `projects.client` → `projects.client_id` conversion - ✅ Missing columns in settings table - ✅ Legacy table structures - ✅ Data preservation ### **Method 2: Manual Migration** #### **Step-by-Step Process:** 1. **Backup Your Database** ```bash # PostgreSQL pg_dump --format=custom --dbname="$DATABASE_URL" --file=backup_$(date +%Y%m%d_%H%M%S).dump # SQLite cp instance/timetracker.db backup_timetracker_$(date +%Y%m%d_%H%M%S).db ``` 2. **Initialize Flask-Migrate** ```bash flask db init ``` 3. **Create Baseline Migration** ```bash flask db migrate -m "Baseline from existing database" ``` 4. **Review Generated Migration** ```bash # Check the generated file in migrations/versions/ cat migrations/versions/*.py ``` 5. **Stamp Database as Current** ```bash flask db stamp head ``` 6. **Apply Any Pending Migrations** ```bash flask db upgrade ``` ### **Method 3: Setup Scripts** #### **Windows:** ```bash scripts\setup-migrations.bat ``` #### **Linux/Mac:** ```bash scripts/setup-migrations.sh ``` #### **Python (Cross-platform):** ```bash python migrations/manage_migrations.py ``` ## 🔍 Pre-Migration Analysis ### **Check Your Current State:** ```bash # Check if Flask-Migrate is available python -c "import flask_migrate; print('✓ Flask-Migrate available')" # Check database connection python -c "from app import create_app; app = create_app(); print('✓ Database accessible')" # Check existing tables (if any) python -c " from app import create_app, db app = create_app() with app.app_context(): inspector = db.inspect(db.engine) tables = inspector.get_table_names() print(f'Existing tables: {tables}') " ``` ### **Common Database States:** | State | Description | Migration Approach | |-------|-------------|-------------------| | **No Database** | Fresh installation | `flask db init` → `flask db migrate` → `flask db upgrade` | | **Empty Database** | Tables exist but no data | `flask db stamp head` → `flask db upgrade` | | **Partial Schema** | Some tables missing | Run comprehensive migration script | | **Legacy Schema** | Old table structures | Run legacy schema migration script | | **Complete Schema** | All tables exist | `flask db stamp head` | ## 🛡️ Safety Measures ### **Automatic Backups:** - ✅ Database backup before any migration - ✅ Timestamped backup files - ✅ Multiple backup formats (dump, copy) - ✅ Backup verification ### **Migration Verification:** - ✅ Schema analysis before migration - ✅ Data integrity checks - ✅ Rollback capability - ✅ Migration status verification ### **Error Handling:** - ✅ Graceful failure handling - ✅ Detailed error messages - ✅ Recovery instructions - ✅ Safe fallback options ## 📋 Migration Checklist ### **Before Migration:** - [ ] **Backup your database** (automatic with scripts) - [ ] **Check disk space** (need space for backup + migration) - [ ] **Stop application** (if running) - [ ] **Verify dependencies** (Flask-Migrate installed) - [ ] **Check permissions** (database access) ### **During Migration:** - [ ] **Run migration script** (automatic or manual) - [ ] **Review generated files** (check migrations/versions/) - [ ] **Verify backup creation** (check backup files) - [ ] **Monitor progress** (watch for errors) ### **After Migration:** - [ ] **Test application** (start and verify functionality) - [ ] **Check migration status** (`flask db current`) - [ ] **Verify data integrity** (check key tables) - [ ] **Update deployment scripts** (if using CI/CD) ## 🔧 Troubleshooting ### **Common Issues & Solutions:** #### **1. Migration Already Applied** ```bash # Check current status flask db current # If migration is already applied, stamp the database flask db stamp head ``` #### **2. Schema Conflicts** ```bash # Show migration heads flask db heads # Merge branches if needed flask db merge -m "Merge migration branches" ``` #### **3. Database Out of Sync** ```bash # Check migration history flask db history # Reset to specific revision flask db stamp ``` #### **4. Permission Errors** ```bash # Check database permissions # Ensure user has CREATE, ALTER, INSERT privileges # For PostgreSQL: GRANT ALL PRIVILEGES ON DATABASE timetracker TO timetracker; ``` #### **5. Connection Issues** ```bash # Verify DATABASE_URL environment variable echo $DATABASE_URL # Test connection manually python -c "from app import create_app; app = create_app(); print('Connection OK')" ``` ### **Recovery Options:** #### **If Migration Fails:** 1. **Check backup files** - your data is safe 2. **Review error logs** - identify the issue 3. **Fix the problem** - resolve conflicts/errors 4. **Restart migration** - run script again #### **If Data is Lost:** 1. **Restore from backup** - use pg_restore or copy SQLite file 2. **Verify restoration** - check data integrity 3. **Contact support** - if issues persist ## 📚 Advanced Migration Scenarios ### **Handling Complex Schema Changes:** #### **Custom Data Migrations:** ```python # In your migration file def upgrade(): # Custom data transformation op.execute("UPDATE users SET role = 'user' WHERE role IS NULL") # Complex table modifications op.execute(""" INSERT INTO new_table (id, name, status) SELECT id, name, 'active' FROM old_table WHERE status = 'enabled' """) ``` #### **Conditional Migrations:** ```python def upgrade(): # Handle different database types if op.get_bind().dialect.name == 'postgresql': op.execute('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"') elif op.get_bind().dialect.name == 'sqlite': # SQLite-specific operations pass ``` #### **Rollback Strategies:** ```python def downgrade(): # Always provide rollback capability op.drop_table('new_table') op.drop_column('existing_table', 'new_column') ``` ## 🚀 Post-Migration ### **Verification Steps:** ```bash # Check migration status flask db current # View migration history flask db history # Test database connection python -c "from app import create_app, db; app = create_app(); print('OK')" # Verify key tables python -c " from app import create_app, db from app.models import User, Project, TimeEntry app = create_app() with app.app_context(): users = User.query.count() projects = Project.query.count() entries = TimeEntry.query.count() print(f'Users: {users}, Projects: {projects}, Entries: {entries}') " ``` ### **Future Migrations:** ```bash # Create new migration flask db migrate -m "Add new feature" # Apply migration flask db upgrade # Rollback if needed flask db downgrade ``` ## 📞 Support & Help ### **Getting Help:** 1. **Check this guide** - covers most scenarios 2. **Review migration logs** - detailed error information 3. **Check Flask-Migrate docs** - https://flask-migrate.readthedocs.io/ 4. **Check Alembic docs** - https://alembic.sqlalchemy.org/ ### **Emergency Recovery:** ```bash # If everything fails, restore from backup # PostgreSQL: pg_restore --clean --dbname="$DATABASE_URL" backup_file.dump # SQLite: cp backup_file.db instance/timetracker.db ``` ## 🎉 Success Indicators Your migration is successful when: - ✅ `flask db current` shows a revision number - ✅ `flask db history` shows migration timeline - ✅ Application starts without database errors - ✅ All existing data is accessible - ✅ New features work correctly - ✅ Backup files are created and accessible --- **Remember**: The migration scripts are designed to be **safe** and **reversible**. Your data is automatically backed up, and you can always restore if needed. When in doubt, run the comprehensive migration script - it handles all scenarios automatically!