Django"无法添加或更新子行:外键约束失败"

Ram*_*hum 66 mysql django orm foreign-keys

我有一个模型Coupon,以及一个Photo带有ForeignKey它的模型:

class Photo(models.Model):
    coupon = models.ForeignKey(Coupon,
                               related_name='description_photos')
    title = models.CharField(max_length=100)
    image = models.ImageField(upload_to='images')
Run Code Online (Sandbox Code Playgroud)

我在管理员中设置内联,所以现在我可以将照片添加到管理员的优惠券中.

我尝试添加一个,上传成功,但后来我得到Django的调试页面,出现此错误:

IntegrityError at /admin/coupon/coupon/321/
(1452, 'Cannot add or update a child row: a foreign key constraint fails (`my_project`.`coupon_photo`, CONSTRAINT `coupon_id_refs_id_90d7f06` FOREIGN KEY (`coupon_id`) REFERENCES `coupon_coupon` (`id`))')
Run Code Online (Sandbox Code Playgroud)

这是什么以及如何解决这个问题?

(如果重要,这是一个MySQL数据库.)

编辑:我在一个Sqlite3数据库上尝试了它,它有一个稍微不同的数据集,并且它有效,所以在我当前的数据库中可能有松散的数据?我怎样才能找到并删除它?

Ram*_*hum 86

我的一些表在InnoDB中,有些在MyISAM中...我将所有内容都更改为MyISAM,问题解决了.

  • +1因为我*从来没有*会自己想到这个. (12认同)
  • 使用`SHOW CREATE TABLE mytable;`来检查数据库引擎. (5认同)
  • 哎呀!我的生命浪费了一个小时因为这个错误...而且因为没有尽快找到答案.谢谢! (3认同)

mmr*_*151 70

DATABASES = {
'default': {
    ...         
    'OPTIONS': {
         "init_command": "SET foreign_key_checks = 0;",
    },
 }
}
Run Code Online (Sandbox Code Playgroud)

(根据官方文档)在以前版本的Django中,使用InnoDB存储引擎时,具有前向引用的装置(即与尚未插入数据库的行的关系)将无法加载.这是因为InnoDB通过立即检查外键约束而不是在事务提交之前推迟检查而偏离SQL标准.这个问题已在Django 1.4中得到解决.

  • 非常感谢!我遇到了这个问题并且感到困惑.我使用Django 1.5与INNODB和南方,我不想手工改变架构的东西! (6认同)
  • 这就是答案:P (4认同)

ApP*_*PeL 19

要避免这种情况发生,您还可以STORAGE_ENGINE在settings.py中设置

对于django> = 1.2

DATABASES = {
    'default': {
        ...
        'STORAGE_ENGINE': 'MyISAM / INNODB / ETC'
    }
}
Run Code Online (Sandbox Code Playgroud)

对于django <= 1.2

DATABASE_STORAGE_ENGINE = "MyISAM / INNODB / ETC"
Run Code Online (Sandbox Code Playgroud)

请注意,这仅适用于MySQL


sup*_*cuo 5

我遇到了同样的问题:mmrs151 的解决方案有效,但请注意,对于Django <= 1.2在多个数据库支持之前),设置如下所示:

DATABASE_OPTIONS = {"init_command": "SET foreign_key_checks = 0;"}
Run Code Online (Sandbox Code Playgroud)

值得注意的是,Ram Rachum 似乎解决了问题,而不是解决了这个问题:MyISAM 根本不支持事务......


Grv*_*agi 5

有时此错误的原因是尝试先保存子表,然后再保存父表。
解决方案是使用。

DATABASES = {
 'default': {
  ...         
 'OPTIONS': {
     "init_command": "SET foreign_key_checks = 0;",
     },
  }
}
Run Code Online (Sandbox Code Playgroud)

2)。检查您的数据库操作流程并使其parent ---> child