Django删除迁移文件后报NodeNotFoundError如何解决
报错根因
手动删除部分迁移文件后,Django迁移依赖链断裂:现存迁移文件app.0172_auto_20220603_1746中声明的前置依赖节点app.0xxx_auto_20220601_2313(即被你手动删除的迁移文件)不存在,迁移加载器构建依赖关系图时找不到对应节点,直接抛出django.db.migrations.exceptions.NodeNotFoundError异常。
修复方案
根据所处环境是否需要保留业务数据,选对应方案处理即可。
场景1:本地开发环境,无需要保留的重要业务数据
该方案处理效率最高,步骤如下:
- 进入报错对应app的
migrations目录,删除除__init__.py之外的所有迁移文件,不要改动其他app的迁移内容 - 清空数据库中迁移记录表的对应app数据,进入数据库执行SQL:
DELETE FROM django_migrations WHERE app = 'app';
如果本地库没有需要保留的业务数据,直接删除对应数据库后重新建库也可以
- 重新生成并执行迁移:
python3 manage.py makemigrations python3 manage.py migrate
执行完成后会生成全新的无断链迁移文件,命令可正常运行。
场景2:生产/测试环境,存在必须保留的业务数据
该场景不能直接删库清数据,按以下步骤修复:
- 定位断链位置:打开报错提示的现存迁移文件
app/migrations/0172_auto_20220603_1746.py,找到类里的dependencies属性,定位到指向已删除的_auto_20220601_2313的依赖项 - 修正依赖指向:把不存在的依赖项,替换为当前
migrations目录下实际存在的、编号小于0172的最新迁移文件。例如删除后0172之前现存的最新迁移是0171_auto_20220530_1234.py,就把对应依赖项改为('app', '0171_auto_20220530_1234')
如果有多个迁移文件都引用了被删除的缺失节点,需要逐个把所有断链依赖修改为指向现存的最近迁移节点
- 伪造迁移对齐状态:被删除的迁移对应的数据库表结构变更实际已经在现有数据库执行过,不需要重复执行,直接用
--fake参数标记迁移状态为已应用:
python3 manage.py migrate --fake app
- 验证修复结果:执行
python3 manage.py showmigrations app,如果所有迁移条目前都标记了[X],再执行makemigrations、showmigrations命令就不会再报节点不存在的错误。
避坑提示
不要随意手动删除项目中的迁移文件,尤其是已经提交到代码库、在生产/公共测试环境执行过的迁移。如果确实需要清理冗余历史迁移,要先确认所有部署环境都已经应用了待清理的迁移,再通过Django自带的squashmigrations功能压缩迁移后统一替换,不要直接物理删除文件造成依赖断链。
内容的提问来源于stack exchange,提问作者Fut Studio
相关产品推荐
相关产品推荐

