Database Migrations
Last updated: October 9, 2026
This guide covers Sophie Bot's database migration system using Beanie ODM.
Overview
Sophie uses Beanie's built-in migration system to manage database schema evolution.
Migrations are versioned, reversible Python scripts that transform data between schema versions.
How It Works
- Migration files are stored in sophie_bot/db/migrations/
- Each migration has a timestamp prefix: YYYYMMDD_HHMMSS_description.py
- Migrations define ForwardandBackwardclasses for apply/rollback
- Applied migrations are tracked in the migration_statescollection
- Migrations run automatically on startup for beta instance
Database initialization also repairs raw ObjectId
filters.chat
values left by the
already-applied 20260125_210117_convert_filters_chat_id_to_link
migration. The repair
runs even when migrations are disabled, preserves each referenced ID, and leaves existing
DBRefs unchanged. Repeated or concurrent startup runs are safe. Fresh migrations write
DBRefs directly.Creating a Migration
Quick Start
Loading...
This creates a file like:
sophie_bot/db/migrations/20240125_120000_add_user_preferences.py
Manual Creation
- Create file: sophie_bot/db/migrations/20240125_120000_add_user_preferences.py
- Define old and new model structures if needed
- Implement Forward and Backward migration classes
- Test migration locally
- Add tests to tests/test_migrations.py
Migration Examples
Example 1: Add New Field
Loading...
Example 2: Rename Field
Loading...
Example 3: Convert Data Type
Loading...
Example 4: Bulk Migration with Free Fall
Loading...
Migration Types
Iterative Migration
When to use:
- Most document transformations
- When you need to transform data field-by-field
- Simple field additions, renames, or type conversions
Pros:
- Beanie handles document loading and saving
- Memory efficient (processes one document at a time)
- Can be resumed if interrupted
- Good for large collections
Cons:
- Limited control over database session
- Can be slower for bulk operations
- Hard to track progress
Free Fall Migration
When to use:
- Bulk operations (rebuilding indexes, collections)
- When you need full database control
- Complex transformations requiring multiple collections
- Performance-critical operations
Pros:
- Full control over database session
- Can use batch processing
- Better performance for bulk operations
- Can track progress manually
Cons:
- More complex to implement
- Must handle document loading/saving manually
- Risk of memory issues with large collections
Running Migrations
Automatic (Recommended for Beta)
Migrations run automatically on startup when
instance_name=beta
:Loading...
Manual
Run all pending migrations:
Loading...
Or invoke the CLI directly:
Loading...
Manual commands run independently of
run_migrations_on_startup
. The CLI opens MongoDB and Redis, initializes Beanie without changing indexes, and closes both clients on success or failure.Check Status
Loading...
Example output:
Loading...
Rollback
Rollback a specific migration:
Loading...
Or invoke the CLI directly:
Loading...
Configuration
Configure migrations in
config.py
:Loading...
Transaction Support
MongoDB transactions provide atomicity for migrations, ensuring either all changes succeed or none do.
Enabling Transactions
- Configure MongoDB replica set (required for transactions)
- Enable replica set in config:
Loading...
When to Use Transactions
Use transactions for:
- Multi-collection migrations
- Critical data transformations
- Rollback safety is essential
- Collections with relational dependencies
Avoid transactions for:
- Very large collections (millions of documents)
- Simple field additions
- Non-critical migrations
- When replica set is not available
Transaction Limitations
MongoDB transactions have limits:
- Document size: 16MB per document
- Transaction size: 16MB total
- Operation count: Varies by MongoDB version
- Execution time: 60 seconds default
For large collections, use free fall migration without transactions.
Handling Large Collections
Batching Strategy
For collections with millions of documents, implement batching:
Loading...
Progress Monitoring
Add progress logging for long-running migrations:
Loading...
Performance Tips
- Use appropriate batch size: 1000-10000 typically works well
- Create indexes before migration: Improves query performance
- Drop indexes before bulk inserts: Faster for large insertions
- Monitor memory usage: Adjust batch size if memory issues occur
- Run during maintenance: Reduces impact on users
Testing
Running Tests
Loading...
Or:
Loading...
Writing Tests
Add tests to
tests/test_migrations.py
:Loading...
Deployment Workflow
- Create migration on development branch
- Test locally: make migrate_up
- Add tests to tests/test_migrations.py
- Test in staging (beta instance)
- Verify status: make migrate_status
- Open merge request with migration details
- CI runs tests automatically
- Merge to main
- Deploy to beta - migrations run automatically
- Verify in beta
- Deploy to stable if needed
Troubleshooting
Migration Failed Mid-Execution
Symptoms:
- Migration error in logs
- Some documents migrated, some not
- Migration state may or may not be recorded
Solutions:
- Check logs for specific error details
- Manually fix affected documents if needed
- Re-run migration - it will skip already-applied steps
- Consider rolling back if state is inconsistent
Loading...
Migration Too Slow
Symptoms:
- Migration taking hours to complete
- High CPU/memory usage
- Database slow to respond
Solutions:
- Use @free_fall_migration()for better control
- Implement batching with migration_batch_size
- Create appropriate indexes before migration
- Consider running during maintenance window
- Monitor and optimize database performance
Loading...
Need to Roll Back
Procedure:
- Stop application to prevent conflicts
- Identify migration to rollback:
Loading...
- Run rollback:
Loading...
- Verify rollback with status check
- Fix migration code if issue was in migration
- Re-apply migration if needed
Important:
- Rollbacks modify data - test in staging first
- Rollbacks may take time for large collections
- Monitor logs during rollback
- Have data backup if possible
Transaction Errors
Symptoms:
- Transaction numbers do not matcherror
- Transaction is not in progresserror
- Migration fails with transaction-related error
Solutions:
- Check MongoDB is running as replica set
- Verify mongo_use_replica_set = Truein config
- Disable transactions for large collections:
Loading...
- Use free fall migration instead
Best Practices
Before Creating Migration
- Document migration purpose and expected changes
- Identify affected models and collections
- Estimate document count for affected collections
- Plan both Forward and Backward logic
- Consider impact on running application
- Add tests for migration
- Update documentation
- Get code review
Before Deploying to Production
- Verify migration passed in CI
- Test in staging environment
- Confirm data integrity after migration
- Document rollback procedure
- Notify team of deployment window
- Monitor logs after deployment
- Verify application functionality
Common Pitfalls
â Don't:
- Create migrations without backward classes
- Skip testing migrations
- Run migrations on production without testing
- Use broad exception handlers that hide errors
- Forget to document migration impact
- Run migrations on stable instance (use beta only)
â
Do:
- Implement both Forward and Backward classes
- Test migrations thoroughly in staging
- Use descriptive migration names
- Handle large collections with batching
- Monitor migration progress with logs
- Document rollback procedures
References
Migration Checklist
Pre-Migration:
- Migration file created with proper naming
- Forward and Backward classes implemented
- Docstring with description and impact
- Tests written in tests/test_migrations.py
- Code reviewed by team
- Tested locally with make migrate_up
- Tested in staging environment
Post-Migration:
- Migration applied successfully
- Data integrity verified
- Application functionality tested
- Performance acceptable
- Logs reviewed for errors
- Documentation updated
- Rollback procedure documented
Production Deployment:
- Staging migration successful
- Rollback procedure documented
- Team notified of deployment
- Maintenance window scheduled (if needed)
- Monitoring configured
- Backup taken (if possible)