feat: add comprehensive database migration system
- Create migrations/ directory with proper structure - Add migration runner (migrations/migrate.py) with tracking - Implement 001_add_description_column.py migration - Add comprehensive README with usage and best practices - Support for ordered execution and rollback capabilities - Integration ready for Docker and CI/CD workflows The migration system provides: - Ordered execution by filename (001_, 002_, etc.) - Applied migration tracking in database - Idempotent operations (safe to re-run) - Standalone and batch execution modes - Comprehensive error handling and logging Restored description column that was missing after merge. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
142
migrations/README.md
Normal file
142
migrations/README.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# Database Migrations
|
||||
|
||||
This directory contains database migrations for the Pet Picture Queue application.
|
||||
|
||||
## Migration System
|
||||
|
||||
The migration system provides:
|
||||
- ✅ **Ordered execution** - Migrations run in filename order (001_, 002_, etc.)
|
||||
- ✅ **Tracking** - Applied migrations are tracked in the database
|
||||
- ✅ **Idempotent** - Safe to run multiple times
|
||||
- ✅ **Rollback support** - Individual migrations can implement rollback logic
|
||||
|
||||
## Usage
|
||||
|
||||
### Run All Pending Migrations
|
||||
```bash
|
||||
# From project root
|
||||
python migrations/migrate.py
|
||||
|
||||
# Or make it executable and run directly
|
||||
chmod +x migrations/migrate.py
|
||||
./migrations/migrate.py
|
||||
```
|
||||
|
||||
### Run Individual Migration
|
||||
```bash
|
||||
python migrations/001_add_description_column.py
|
||||
```
|
||||
|
||||
## Migration Structure
|
||||
|
||||
Each migration file should follow this pattern:
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Migration XXX: Description of what this migration does
|
||||
Date: YYYY-MM-DD
|
||||
Description: Detailed explanation
|
||||
"""
|
||||
|
||||
import sqlite3
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
def migrate_up(cursor):
|
||||
"""Apply the migration"""
|
||||
# Your migration code here
|
||||
cursor.execute("ALTER TABLE ...")
|
||||
return True # or False if skipped
|
||||
|
||||
def migrate_down(cursor):
|
||||
"""Rollback the migration (optional)"""
|
||||
# Rollback code here
|
||||
return True
|
||||
|
||||
def main():
|
||||
"""Run migration standalone"""
|
||||
# Standard standalone execution code
|
||||
pass
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
```
|
||||
|
||||
## Existing Migrations
|
||||
|
||||
### 001_add_description_column.py
|
||||
- **Purpose**: Add description field to pet_pictures table
|
||||
- **Date**: 2025-08-08
|
||||
- **Changes**: Adds `description TEXT NULL` column
|
||||
|
||||
## Migration Naming Convention
|
||||
|
||||
- Use 3-digit numbers: `001_`, `002_`, `003_`, etc.
|
||||
- Descriptive names: `add_description_column`, `create_user_table`
|
||||
- Full format: `XXX_descriptive_name.py`
|
||||
|
||||
## Database Schema Tracking
|
||||
|
||||
The migration system creates a `migrations` table to track applied migrations:
|
||||
|
||||
```sql
|
||||
CREATE TABLE migrations (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
migration_name TEXT NOT NULL UNIQUE,
|
||||
applied_at TIMESTAMP NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always backup** before running migrations on production data
|
||||
2. **Test migrations** on development data first
|
||||
3. **Make migrations idempotent** - check if changes already exist
|
||||
4. **Keep migrations small** - one logical change per migration
|
||||
5. **Never edit** existing migration files after they've been applied
|
||||
6. **Document breaking changes** in migration comments
|
||||
|
||||
## Development Workflow
|
||||
|
||||
1. **Create migration**: Copy template and modify
|
||||
2. **Test locally**: Run migration on development database
|
||||
3. **Add to version control**: Commit the migration file
|
||||
4. **Deploy**: Run migrations on staging/production
|
||||
5. **Verify**: Check database schema and data integrity
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Migration fails:**
|
||||
```bash
|
||||
# Check database connection
|
||||
ls -la pet_pictures.db
|
||||
|
||||
# Check migration table
|
||||
sqlite3 pet_pictures.db "SELECT * FROM migrations;"
|
||||
|
||||
# Run specific migration for debugging
|
||||
python migrations/001_add_description_column.py
|
||||
```
|
||||
|
||||
**Reset migration tracking:**
|
||||
```sql
|
||||
-- Careful! This will re-run all migrations
|
||||
DELETE FROM migrations WHERE migration_name = '001_add_description_column';
|
||||
```
|
||||
|
||||
## Integration
|
||||
|
||||
### Docker
|
||||
The migration runner is integrated with Docker:
|
||||
```bash
|
||||
# Run migrations in Docker
|
||||
docker compose --profile migrate up migrate
|
||||
```
|
||||
|
||||
### CI/CD
|
||||
Add to deployment scripts:
|
||||
```bash
|
||||
# Run migrations before starting app
|
||||
python migrations/migrate.py && python main.py
|
||||
```
|
||||
Reference in New Issue
Block a user