外键约束不允许从django中的表中删除行

时间:2016-09-27 12:38:28

标签: mysql django

我在Django中创建了以下模型。

class ClientsModel(models.Model):
    sys_id = models.AutoField(primary_key=True, null=False, blank=True)
    tenant_sys_id = models.ForeignKey('tenant.TenantModel', on_delete = models.SET_NULL, null=True, blank=True)
    last_name = models.CharField(max_length=40, null=True, blank=True)
    # and few more rows.

此处tenant_sys_id是外键。我设置了on_delete = models.SET_NULL,这意味着如果我从TenantModel中删除任何条目(比如说entry1),那么将tenant_sys_id作为entry1的所有行中的列tenant_sys_id都应设置为null。我在这儿?
如果是 - 那么这是下一个问题。如果我尝试从mysql中删除租户表中的条目,那么它会让我误解为错误。

mysql> delete from tenants where sys_id = 1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`sanstha_db`.`clients`, CONSTRAINT `Clients_tenant_sys_id_id_52191b87_fk_Tenants_sys_id` FOREIGN KEY (`tenant_sys_id_id`) REFERENCES `tenants` (`sys_id`))

这是表结构。

Table: clients
Create Table: CREATE TABLE `clients` (
  `sys_id` int(11) NOT NULL AUTO_INCREMENT,
  `last_name` varchar(40) DEFAULT NULL,
  `first_name` varchar(40) NOT NULL,
  `middle_name` varchar(40) DEFAULT NULL,
  `display_name` varchar(140) NOT NULL,
  `is_business` tinyint(1) NOT NULL,
  `is_active` tinyint(1) NOT NULL,
  `is_vendor` tinyint(1) NOT NULL,
  `is_authorized_to_expense` tinyint(1) NOT NULL,
  `relation` bigint(20) DEFAULT NULL,
  `dob` date DEFAULT NULL,
  `gender` bigint(20) DEFAULT NULL,
  `created_when` datetime DEFAULT NULL,
  `created_by` bigint(20) DEFAULT NULL,
  `last_updated_when` datetime DEFAULT NULL,
  `last_updated_by` bigint(20) DEFAULT NULL,
  `notes` varchar(2048) DEFAULT NULL,
  `head_of_family_id` int(11) DEFAULT NULL,
  `tenant_sys_id_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`sys_id`),
  KEY `Clients_head_of_family_id_01c17980_fk_Clients_sys_id` (`head_of_family_id`),
  KEY `Clients_tenant_sys_id_id_52191b87_fk_Tenants_sys_id` (`tenant_sys_id_id`),
  CONSTRAINT `Clients_head_of_family_id_01c17980_fk_Clients_sys_id` FOREIGN KEY (`head_of_family_id`) REFERENCES `clients` (`sys_id`),
  CONSTRAINT `Clients_tenant_sys_id_id_52191b87_fk_Tenants_sys_id` FOREIGN KEY (`tenant_sys_id_id`) REFERENCES `tenants` (`sys_id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=latin1

请建议我为什么不让我删除该条目?什么是正确的方法。

1 个答案:

答案 0 :(得分:1)

所以这就是问题所在。

on_delete = models.SET_NULL会将foreign key(您在父表中删除的)的值替换为null值。

但上述内容将由 Django 完成,当您在views.py中写一些逻辑以删除某些tenants模型时,on_delete = Models.SET_NULL Django 中定义的内容,而不是 MySQL 中定义的内容。

因此,当你在views.py中执行此操作时,Django会对其进行解释,然后在模型ClientsModel中使外键为null,之后只删除模型中的行{{1} }。

但是,如果您使用 MySQL 命令行从另一个终端执行此操作,那么您不会与Django交互并直接删除表tenants中的行。这样,模型tenants中的外键将不会设置为 null ,因此您将获得ClientsModel

最后,你最后评论的答案。如果从Django中删除一行,无论是否使用Django的ORM或原始SQL查询,都不会出现此错误。