Django报IntegrityError创建唯一索引失败 模型无唯一约束如何解决
报错原因
这个报错的核心原因是生产环境执行迁移的过程中,需要给Player表的player字段创建唯一索引,但表中已存在重复的player值导致创建失败,和你当前模型里有没有写唯一约束没有直接关系,问题出在迁移文件的累积逻辑上,常见的诱因有3种:
- 你中途开发的时候曾经误给
Player.player字段加过unique=True参数,生成了对应添加唯一约束的迁移文件,后续你删掉了这个参数但没有生成移除唯一约束的新迁移文件,生产执行迁移时还是会走到加约束的步骤 - 本地开发时你删除过旧的迁移文件重新生成,本地迁移历史和生产环境已执行的迁移历史不一致,本地生成的新迁移逻辑漏了对旧约束的处理
- 你之前修改
apiid的唯一约束或者APIPlayerGW的联合唯一约束时,生成的迁移文件出现逻辑错误,误将唯一约束加到了Player.player字段上
排查步骤
- 进入对应Django App的
migrations目录,全局搜索所有迁移文件中的unique关键字,定位到哪份迁移文件包含了给Player表player字段加唯一索引的操作 - 在生产环境执行
python manage.py showmigrations,核对未执行的迁移列表,确认出问题的迁移文件
解决方法
根据你的实际情况选对应方案:
方案1:出问题的迁移还未在生产执行
- 直接删除包含错误加唯一约束逻辑的迁移文件
- 本地重新执行
python manage.py makemigrations生成正确的迁移文件 - 将新的迁移文件更新到生产环境,执行
python manage.py migrate即可 - 额外注意:你注释了
APIPlayerGW的unique_together配置后,必须单独生成移除该联合约束的迁移,不要直接注释就不做迁移操作,否则之前加联合约束的迁移步骤还是会执行
方案2:出问题的迁移已经在生产执行到一半卡住
- 先执行
python manage.py migrate --fake [你的App名称] [上一个正常执行完成的迁移文件名],将迁移记录伪回退到出错步骤之前(不会改动实际表结构) - 删掉错误的迁移文件,重新生成正确的迁移文件
- 到生产环境执行
python manage.py migrate完成迁移
注意事项
不要随意删除已经提交到代码仓库、已经在生产环境执行过的迁移文件,否则很容易出现本地和生产迁移历史不一致的问题,后续会反复出现类似的表结构错误。
内容的提问来源于stack exchange,提问作者embe
相关产品推荐
相关产品推荐

