Files
TimeTracker/migrations/MIGRATION_GUIDE.md
T
Dries Peeters d9dab3a49c feat: enhance README with comprehensive screenshot showcase
- Add organized screenshot sections for better visual presentation
- Include all 12 available screenshots from assets/screenshots/
- Group screenshots into logical categories:
  * Core Application Views (Dashboard, Projects, Tasks, Clients)
  * Management & Analytics (Reports, Visual Analytics, Task Management, Admin)
  * Data Entry & Creation (Log Time, New Task, New Client, New Project)
- Improve visual layout with proper spacing and responsive design
- Enhance user experience by showcasing full application capabilities
2025-09-02 14:42:54 +02:00

359 lines
9.1 KiB
Markdown

# 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" <revision1> <revision2>
```
#### **3. Database Out of Sync**
```bash
# Check migration history
flask db history
# Reset to specific revision
flask db stamp <revision>
```
#### **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!