第5章:数据库操作
5.2 Django 迁移系统
迁移概念
Django的迁移系统是一个版本控制系统,用于管理数据库模式的变更。它允许开发者:
- 跟踪数据库模式的变化
- 在不同环境之间同步数据库结构
- 回滚不需要的数据库变更
迁移命令
创建迁移文件
bash
# 为所有已更改的模型创建迁移文件
python manage.py makemigrations
# 为特定应用创建迁移文件
python manage.py makemigrations app_name
# 为特定模型创建迁移文件
python manage.py makemigrations app_name --name migration_name
# 空迁移文件(手动编写迁移操作)
python manage.py makemigrations --empty app_name应用迁移
bash
# 应用所有未应用的迁移
python manage.py migrate
# 为特定应用应用迁移
python manage.py migrate app_name
# 应用到特定迁移版本
python manage.py migrate app_name 0002_some_migration
# 显示迁移状态
python manage.py showmigrations回滚迁移
bash
# 回滚到上一个迁移版本
python manage.py migrate app_name previous_migration_number
# 回滚所有迁移(重置数据库)
python manage.py migrate app_name zero迁移文件解析
迁移文件位于每个应用的 migrations/ 目录中,文件名格式为 0001_initial.py:
python
# 示例迁移文件
from django.db import migrations, models
class Migration(migrations.Migration):
# 依赖关系
dependencies = [
('app_name', '0001_initial'),
]
# 数据库操作
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),
),
]迁移操作类型
Django提供了多种迁移操作:
1. 模型操作
python
migrations.CreateModel(
name='ModelName',
fields=[...],
options={...},
bases=(...),
)
migrations.DeleteModel(name='ModelName')2. 字段操作
python
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. 索引和约束
python
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'),
)数据迁移
除了模式迁移,还可以创建数据迁移:
bash
# 创建空的数据迁移文件
python manage.py makemigrations --empty app_name然后在生成的迁移文件中添加数据操作:
python
from django.db import migrations
def add_initial_data(apps, schema_editor):
# 获取模型类
Article = apps.get_model('blog', 'Article')
# 创建初始数据
Article.objects.create(
title='欢迎使用Django',
content='这是第一篇文章内容...',
published=True
)
def reverse_data(apps, schema_editor):
# 回滚操作
Article = apps.get_model('blog', 'Article')
Article.objects.filter(title='欢迎使用Django').delete()
class Migration(migrations.Migration):
dependencies = [
('blog', '0001_initial'),
]
operations = [
migrations.RunPython(add_initial_data, reverse_data),
]自定义迁移操作
可以创建自定义的迁移操作:
python
from django.db import migrations, models
class CustomOperation(migrations.Operation):
reversible = True
def state_forwards(self, app_label, state):
# 修改状态
pass
def database_forwards(self, app_label, schema_editor, from_state, to_state):
# 数据库前进操作
pass
def database_backwards(self, app_label, schema_editor, from_state, to_state):
# 数据库回滚操作
pass迁移依赖关系
迁移文件可以指定依赖关系:
python
class Migration(migrations.Migration):
# 依赖其他应用的迁移
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
('contenttypes', '0002_remove_content_type_name'),
]
# 依赖同一应用的其他迁移
dependencies = [
('blog', '0001_initial'),
]迁移最佳实践
1. 小步提交
bash
# 每次只做一个小的变更
python manage.py makemigrations
python manage.py migrate2. 测试迁移
bash
# 在测试环境中测试迁移
python manage.py test --migrate3. 版本控制
bash
# 将迁移文件纳入版本控制
git add app/migrations/4. 处理冲突
bash
# 当迁移冲突时,可以手动合并或重新生成
python manage.py makemigrations --merge常见问题解决
迁移冲突
当多个开发者同时创建迁移时可能发生冲突:
bash
# 查看冲突
python manage.py showmigrations --conflict
# 合并冲突
python manage.py makemigrations --merge重置迁移
在开发早期可以重置迁移:
bash
# 删除所有迁移文件
find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
find . -path "*/migrations/*.pyc" -delete
# 重新创建初始迁移
python manage.py makemigrations
python manage.py migrate手动修改迁移
有时需要手动编辑迁移文件:
python
# 修改依赖关系
dependencies = [
('app_name', '0001_initial'),
# 添加额外的依赖
('other_app', '0002_some_migration'),
]
# 修改操作顺序
operations = [
# 调整操作顺序
migrations.AddField(...),
migrations.AlterField(...),
]生产环境迁移
在生产环境中执行迁移需要谨慎:
bash
# 先备份数据库
python manage.py dumpdata > backup.json
# 测试迁移
python manage.py migrate --dry-run
# 应用迁移
python manage.py migrate
# 如果有问题,回滚
python manage.py migrate app_name previous_version迁移工具和扩展
Django Migration Linter
检查迁移文件的兼容性问题:
bash
pip install django-migration-linter
python manage.py lintmigrationsDjango-Tenants
多租户数据库迁移:
bash
pip install django-tenants
python manage.py migrate_schemas小结
Django迁移系统是数据库版本控制的强大工具:
- ✅ 通过
makemigrations和migrate命令管理数据库变更 - ✅ 支持模式迁移和数据迁移
- ✅ 提供回滚和冲突解决机制
- ✅ 支持多数据库和自定义操作
- ✅ 生产环境安全迁移的最佳实践
掌握迁移系统能够确保数据库结构变更的安全性和一致性。
下一篇
我们将学习QuerySet和数据库API,了解如何高效地查询和操作数据。