【问题标题】:foreign key constraint not letting delete row from table in django外键约束不允许从 Django 中的表中删除行
【发布时间】:2016-09-27 12:38:28
【问题描述】:

我在 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

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

【问题讨论】:

  • 它说你对clients 表有问题,而不是users
  • 哦...对不起...更新问题。
  • 您显示的模型具有tenant_sys_id 作为foreign key。你是说parent_sys_idforeign key。那么还有更多Models 还是您错误地将tenant_sys_id 写为parent_sys_id。因为上面对我来说真的没有意义。如果你上面写的没有错误,你能用一个更好的例子来解释这个场景吗?
  • @AnkushRaghuvanshi - 更新了问题......有一个错误......之前我使用了另一个模型。
  • 您是在 views 中进行 原始 sql 查询,还是使用 mysql 命令行在另一个终端中进行该查询。因为如果是前一种情况,那么我知道问题所在。

标签: mysql django


【解决方案1】:

这就是问题所在。

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

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

因此,当您在 views.py 中执行此操作时,Django 会对其进行解释,然后使模型 ClientsModel 中的外键为空,然后才从模型 tenants 中删除该行。

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

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

【讨论】:

  • 谢谢...知道了...但是这些表是由 django 正确创建的...那么为什么 django 没有以我们可以在终端中处理这种情况的方式创建表.. .
  • Django 只是一个框架。 MySQL 和 Django 是相互独立的。您可以使用任何其他后端框架来做同样的事情,并使用 MySQL 作为您的数据库。框架是一个层,您可以在其中纠正前端如何与数据库交互的逻辑。所以 Django 有一些内置特性,可以以特定方式写入数据库,但不能改变数据库行为的特征属性,无论是 MySQL、PostgreSQL 还是 Mongo。
  • 如果您将使用python manage.py shell 删除行,那么它肯定会被处理并且您不会收到错误,因为现在您正在与您的数据库进行交互通过 姜戈。但显然,如果你在另一个终端中使用mysql -u root -p 并直接删除一行而不让 Django 知道,你会得到错误。
猜你喜欢
  • 2015-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-09
相关资源
最近更新 更多