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

标签 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

请告诉我为什么它不允许我删除该条目?正确的做法是什么?

最佳答案

所以这里有一个问题。

on_delete = models.SET_NULL 将用 null 值替换该外键(您在父表中删除的)的值。

但是当你在 views.py 中编写一些逻辑来删除一些租户模型行时,上面的操作将由 Django 完成,因为 on_delete = Models.SET_NULL 是在 Django 中定义的,而不是在 MySQL 中定义的。

因此,当您在 views.py 中执行此操作时,Django 会对其进行解释,然后在模型 ClientsModel 中将外键设置为空,并且仅在此之后它才会删除来自模型租户的行。

但是,如果您使用 MySQL 命令行从另一个终端执行此操作,则您不会与 Django 交互,也不会直接从表 tenants 中删除该行。这样,模型 ClientsModel 中的外键将不会设置为 null,因此您将收到外键约束错误

最后,对您上一条评论的回答。如果从 Django 删除一行,无论您使用 Django 的 ORM 还是原始 SQL 查询,都不会收到此错误。

关于mysql - 外键约束不允许从 django 中的表中删除行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39724907/

相关文章:

php - 如何使用 android 中的 volley 库将数据保存到 mysql?

php - 如何使用 Doctrine 更改 mysql 表的 auto_increment

java - 使用 JDBC 在 mysql 表中插入和更新

php - 为mysql生成数字顺序

Django:prefetch_related() 是否遵循反向关系查找?

mysql - 即使该日期没有数据(在这种情况下,该行应该用零填充),如何为每个日期返回一行?

python - django - 部署到 Heroku : Server Error(500)

html - Django:CSS 文件不会更新

django - 用于修剪任何前导或尾随空格的模板过滤器

python - 谷歌应用引擎 : get_or_create()?