Django 迁移数据库时报 MigrationConflictError 怎么修复?

文章导读
遇到 MigrationConflictError 通常是因为迁移历史出现了分叉,最稳妥的做法是使用 Django 自带的合并命令生成新的迁移文件,而不是手动修改现有文件。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 参考来源
A A

遇到 MigrationConflictError 通常是因为迁移历史出现了分叉,最稳妥的做法是使用 Django 自带的合并命令生成新的迁移文件,而不是手动修改现有文件。

先说结论:这是迁移图出现了多个头节点,需要合并分支才能继续。

  • 先确认:运行 showmigrations 查看是否有多个标记为未应用的头节点
  • 先处理:使用 makemigrations `--merge` 自动生成合并迁移文件(CI/CD 环境需加 `--noinput`)
  • 再验证:再次运行 showmigrations 确认只剩一个头节点后执行 migrate

命令速用版

本地开发环境直接运行:

python manage.py makemigrations `--merge`
python manage.py migrate

如果是特定应用冲突,指定 app 名称:

python manage.py makemigrations `--merge` your_app_name

注意:在 CI/CD 流水线或非交互环境中,必须添加 `--noinput` 参数,否则命令会等待输入导致进程挂起:

python manage.py makemigrations `--merge` `--noinput`

为什么会这样

Django 的迁移系统依赖一个有向无环图来记录数据库结构变化。当多个开发者基于同一个迁移文件分别创建了新的迁移,或者手动调整了迁移依赖关系,就会导致图中出现多个“叶子节点”。Django 不知道应该先应用哪一个,因此抛出冲突错误。

分步处理

1. 检查迁移状态

Django 迁移数据库时报 MigrationConflictError 怎么修复?
python manage.py showmigrations

观察输出,如果看到某个 app 下有两个或多个未应用的迁移文件并列(通常标记为 [ ] 且没有先后依赖),说明存在冲突。

2. 自动合并迁移

python manage.py makemigrations `--merge`

系统会提示你确认合并,输入 yes 后会在 migrations 目录下生成一个新的迁移文件,其 dependencies 包含冲突的两个父节点。

3. 手动修复依赖(仅当自动合并失败时)

如果自动合并不成功,需要手动编辑新生成的迁移文件。打开文件找到 dependencies 列表,确保它明确包含了冲突的两个迁移文件名称。例如:

dependencies = [
    ('your_app', '0001_initial'),
    ('your_app', '0002_auto'),
]

修改保存后,再次运行迁移命令。

Django 迁移数据库时报 MigrationConflictError 怎么修复?

4. 应用迁移

python manage.py migrate

怎么验证是否生效

再次运行 python manage.py showmigrations,确认每个 app 的迁移链是线性的,没有分叉。同时检查数据库迁移记录表(通常是 django_migrations),确保新生成的合并迁移已被记录。

常见坑

1. 不要随意删除迁移文件:除非你确定数据库状态干净,否则删除已应用的迁移文件会导致后续无法追踪。

2. 团队协作规范:合并代码前先拉取最新代码并运行迁移,避免多人基于旧版本创建新迁移。

3. 自动化流程卡住:在 Jenkins、GitLab CI 等环境中,务必使用 `--noinput` 参数,否则迁移步骤会因等待确认而超时失败。

4. 手动编辑风险:手动修改 dependencies 容易出错,优先使用 `--merge` 参数,只有在自动合并不满足需求时才人工干预。

参考来源

  • Django 官方文档 - Migrations: https://docs.djangoproject.com/en/stable/topics/migrations/