如何规避含显式插入的Django迁移触发InconsistentMigrationHistory异常
全环境兼容的迁移适配方案
核心冲突本质
Django的迁移校验逻辑会严格比对数据库django_migrations表中记录的已执行迁移时序,和本地迁移文件声明的依赖关系是否完全一致。之前直接修改已上线的002_inserts_products、让其依赖后序003_modify_products的操作,本质是强行篡改了生产环境已经固化的迁移历史时序——生产环境早已记录002在003之前执行完成,和新的依赖规则完全不匹配,因此才会触发InconsistentMigrationHistory报错。
分步骤落地操作
- 第一步:先消除生产环境的一致性校验报错
撤回之前给002_inserts_products新增的对003_modify_products的依赖声明,还原002原有仅依赖001_products的配置;同时保留003_modify_products原有对002的依赖配置不变。
该操作仅调整迁移的依赖声明,完全不改动001、002迁移的历史执行逻辑,不会影响生产环境已经存储的业务数据,核心作用是让迁移校验逻辑和生产环境已经留存的历史记录完全匹配,先打通生产环境执行后续迁移的通路。 - 第二步:适配全新测试/本地环境的执行时序要求
不对已经上线的001、002迁移的操作逻辑做破坏性调整,通过抽离逻辑+新增独立迁移的方式解决顺序冲突:- 将
002_inserts_products中所有插入初始数据的操作(包括RunPython、RunSQL的执行内容)全部移除,把002改造为无实际操作的空迁移,保留原有迁移文件名、应用归属、对001的依赖关系——生产环境因为早已将002标记为已执行,根本不会重新运行这个空迁移,对生产流程完全透明。 - 新增独立迁移文件(如
004_seed_products_initial_data),把之前从002中抽离的所有初始数据插入逻辑全部迁移到这个新迁移中,给新迁移设置双重依赖:一是基础建表迁移001_products,二是表结构变更迁移003_modify_products。 - 给新迁移的插入逻辑增加前置存在性判断:插入初始数据前,先查询
Products表中是否存在初始数据的唯一标识(如固定业务产品的SKU、预设主键值),如果数据已存在就直接跳过插入操作,避免在已经执行过旧版002的生产环境重复写入数据。
- 将
多环境执行效果校验
按照上述方案调整后,不同环境的迁移流程会自动匹配自身基线:
- 生产环境:按历史记录匹配001→002的执行顺序,无一致性校验报错;后续自动执行未跑过的
003_modify_products完成表结构变更,再执行新的004_seed_products_initial_data时,会因为检测到初始数据已存在直接跳过,不会影响存量数据。 - 全新测试/本地环境:执行顺序为001建表→002空操作→003完成新表结构调整→004在新表结构下插入初始数据,彻底解决之前“先插入旧结构数据、再修改表结构导致测试用例失败”的问题。
避坑提醒:绝对不要删除已经上线的迁移文件、也不要修改已上线迁移的文件名和应用归属,否则会直接导致生产环境的迁移历史完全匹配失败。
内容的提问来源于stack exchange,提问作者Marcel
相关产品推荐
相关产品推荐

