Django报错修复:1452, ‘Cannot add or update a child row: a foreign key constraint fails

Posted zeaning

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django报错修复:1452, ‘Cannot add or update a child row: a foreign key constraint fails相关的知识,希望对你有一定的参考价值。

Django admin后台,修改User表数据时,遇到报错:

django.db.utils.IntegrityError: (1452, 'Cannot add or update a child row: a foreign key constraint fails (`auto_center`.`django_admin_log`, CONSTRAINT `django_admin_log_user_id_c564eba6_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`))')

网上查了下,基本上都是说修改setting文件的databases,添加以下代码取消外键检查:

'OPTIONS': 
    "init_command": "SET foreign_key_checks = 0;",

但是,取消外键检查,会导致外键约束检查失效,会有隐患,乃是治标不治本的方法。

看报错的信息,是django_admin_log表的user_id,指向了外键是auth_user。但我的Django User模型有个扩展表,是指向了扩展的User表,而非Django原生的auth_user表。

查看django_admin_log源码,是指向settings.AUTH_USER_MODEL的。而我在settings里,已经配置过指向扩展User表了:

AUTH_USER_MODEL = 'auth.ExpandUser'

配置是生效的。我切换到测试环境,是不会有上面报错了,相同代码,只是切换了数据库,就会有报错。说明不是代码问题。

仔细思考了下,应该是线上环境,比较久远了,当初执行migrate的时候,django_admin_log表的user_id,指向了原生的auth_user。后来更新了扩展User表,测试环境的数据库是重新建立过的,重新执行的migrate,所以关联的外键是扩展User表,不会报错。

所以问题的原因必然是在现有的线上数据库的记录上。查了一圈,找到原因。是django_admin_log表的user_id字段,关联了外键auth_user。而测试环境的是关联的扩展User表。

在这里的引用表,修改成ExpandUser表。再回到admin后台修改User表数据 ,不再报错。

反思一下:之前一直是用Django的ORM管理映射关系的,不知道mysql原生的外键是怎么管理的。今天遇到的问题,排查下来,就是由于历史的migrate记录,导致扩展User表的时候,数据库还记录旧的外键关系。而admin操作修改的时候,会记录日志到django_admin_log,记录user_id的时候,使用ExpandUser表的user_id记录到数据库时,触发了MySQL检查外键,指向auth_user表,而auth_user没有对应的user_id,就报错了。

知道原因,再回过头来看修复方法,就很简单了:

  1. 修改django_admin_log,把user_id关联的外键,改成自己定义的扩展User表
  2. 如果不想改,可以在测试环境(或新建个空的数据库),重新执行迁移,然后把新的django_admin_log表,通过数据库复制的方式,覆盖掉现有的django_admin_log表

以上是关于Django报错修复:1452, ‘Cannot add or update a child row: a foreign key constraint fails的主要内容,如果未能解决你的问题,请参考以下文章

Django报错修复:1452, ‘Cannot add or update a child row: a foreign key constraint fails

MySQL设置外键报错 #1452 - Cannot add or update a child row: a foreign key constraint fails 解决方法

Django Admin后台添加用户时出现报错:1452

django报错信息解决办法

ERROR 1452 : Cannot add or update a child row: a foreign key constraint fails

Django报错ImportError: cannot import name ‘ugettext_lazy‘ from ‘django.utils.translation‘