Chapter 5: Database Operations
5.2 Django Migration System
Migration Concept
Django's migration system is a version control system for managing database schema changes. It allows developers to:
- Track changes to database schemas
- Synchronize database structures across different environments
- Roll back unwanted database changes
Migration Commands
Creating Migration Files
# Create migration files for all changed models
python manage.py makemigrations
# Create migration files for a specific app
python manage.py makemigrations app_name
# Create migration files for a specific model
python manage.py makemigrations app_name --name migration_name
# Empty migration file (manually write migration operations)
python manage.py makemigrations --empty app_nameApplying Migrations
# Apply all unapplied migrations
python manage.py migrate
# Apply migrations for a specific app
python manage.py migrate app_name
# Apply to a specific migration version
python manage.py migrate app_name 0002_some_migration
# Show migration status
python manage.py showmigrationsRolling Back Migrations
# Roll back to the previous migration version
python manage.py migrate app_name previous_migration_number
# Roll back all migrations (reset database)
python manage.py migrate app_name zeroMigration File Analysis
Migration files are located in the migrations/ directory of each app, with file names in the format 0001_initial.py:
# Example migration file
from django.db import migrations, models
class Migration(migrations.Migration):
# Dependencies
dependencies = [
('app_name', '0001_initial'),
]
# Database operations
operations = [
migrations.CreateModel(
name='Article',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=200)),
('content', models.TextField()),
('created_at', models.DateTimeField(auto_now_add=True)),
],
),
migrations.AddField(
model_name='article',
name='published',
field=models.BooleanField(default=False),
),
]Migration Operation Types
Django provides various migration operations:
1. Model Operations
migrations.CreateModel(
name='ModelName',
fields=[...],
options={...},
bases=(...),
)
migrations.DeleteModel(name='ModelName')2. Field Operations
migrations.AddField(
model_name='modelname',
name='fieldname',
field=models.CharField(max_length=100),
)
migrations.RemoveField(
model_name='modelname',
name='fieldname',
)
migrations.AlterField(
model_name='modelname',
name='fieldname',
field=models.TextField(),
)3. Indexes and Constraints
migrations.AddIndex(
model_name='modelname',
index=models.Index(fields=['field1', 'field2'], name='index_name'),
)
migrations.AddConstraint(
model_name='modelname',
constraint=models.UniqueConstraint(fields=['field1', 'field2'], name='constraint_name'),
)Data Migrations
In addition to schema migrations, data migrations can also be created:
# Create an empty data migration file
python manage.py makemigrations --empty app_nameThen add data operations in the generated migration file:
from django.db import migrations
def add_initial_data(apps, schema_editor):
# Get model class
Article = apps.get_model('blog', 'Article')
# Create initial data
Article.objects.create(
title='Welcome to Django',
content='This is the first article content...',
published=True
)
def reverse_data(apps, schema_editor):
# Rollback operation
Article = apps.get_model('blog', 'Article')
Article.objects.filter(title='Welcome to Django').delete()
class Migration(migrations.Migration):
dependencies = [
('blog', '0001_initial'),
]
operations = [
migrations.RunPython(add_initial_data, reverse_data),
]Custom Migration Operations
Custom migration operations can be created:
from django.db import migrations, models
class CustomOperation(migrations.Operation):
reversible = True
def state_forwards(self, app_label, state):
# Modify state
pass
def database_forwards(self, app_label, schema_editor, from_state, to_state):
# Database forward operation
pass
def database_backwards(self, app_label, schema_editor, from_state, to_state):
# Database rollback operation
passMigration Dependencies
Migration files can specify dependencies:
class Migration(migrations.Migration):
# Depend on migrations from other apps
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
('contenttypes', '0002_remove_content_type_name'),
]
# Depend on other migrations from the same app
dependencies = [
('blog', '0001_initial'),
]Migration Best Practices
1. Small Commits
# Make only small changes at a time
python manage.py makemigrations
python manage.py migrate2. Test Migrations
# Test migrations in test environment
python manage.py test --migrate3. Version Control
# Include migration files in version control
git add app/migrations/4. Handling Conflicts
# When migration conflicts occur, merge manually or regenerate
python manage.py makemigrations --mergeCommon Problem Solutions
Migration Conflicts
Conflicts may occur when multiple developers create migrations simultaneously:
# View conflicts
python manage.py showmigrations --conflict
# Merge conflicts
python manage.py makemigrations --mergeResetting Migrations
Migrations can be reset during early development:
# Delete all migration files
find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
find . -path "*/migrations/*.pyc" -delete
# Recreate initial migrations
python manage.py makemigrations
python manage.py migrateManual Migration Modification
Sometimes migration files need to be manually edited:
# Modify dependencies
dependencies = [
('app_name', '0001_initial'),
# Add additional dependencies
('other_app', '0002_some_migration'),
]
# Modify operation order
operations = [
# Adjust operation order
migrations.AddField(...),
migrations.AlterField(...),
]Production Environment Migrations
Executing migrations in production environments requires caution:
# Backup database first
python manage.py dumpdata > backup.json
# Test migration
python manage.py migrate --dry-run
# Apply migration
python manage.py migrate
# If there's a problem, roll back
python manage.py migrate app_name previous_versionMigration Tools and Extensions
Django Migration Linter
Check migration file compatibility issues:
pip install django-migration-linter
python manage.py lintmigrationsDjango-Tenants
Multi-tenant database migrations:
pip install django-tenants
python manage.py migrate_schemasSummary
Django migration system is a powerful tool for database version control:
- ✅ Manage database changes through
makemigrationsandmigratecommands - ✅ Support schema migrations and data migrations
- ✅ Provide rollback and conflict resolution mechanisms
- ✅ Support multi-database and custom operations
- ✅ Best practices for safe migrations in production environments
Mastering the migration system ensures the safety and consistency of database structure changes.
Next
We will learn about QuerySet and database API, understanding how to efficiently query and manipulate data.
5.3 QuerySet and Database API →