Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何临时禁用MySQL中的外键约束?_Mysql_Sql_Django_Django Models - Fatal编程技术网

如何临时禁用MySQL中的外键约束?

如何临时禁用MySQL中的外键约束?,mysql,sql,django,django-models,Mysql,Sql,Django,Django Models,可以暂时禁用MySQL中的约束吗 我有两个Django模型,每个模型都有一个外键指向另一个。由于外键约束,删除模型实例会返回错误: cursor.execute("DELETE FROM myapp_item WHERE n = %s", n) transaction.commit_unless_managed() #a foreign key constraint fails here cursor.execute("DELETE FROM myapp_sty

可以暂时禁用MySQL中的约束吗

我有两个Django模型,每个模型都有一个外键指向另一个。由于外键约束,删除模型实例会返回错误:

cursor.execute("DELETE FROM myapp_item WHERE n = %s", n)
transaction.commit_unless_managed()  #a foreign key constraint fails here

cursor.execute("DELETE FROM myapp_style WHERE n = %s", n)
transaction.commit_unless_managed()
SET GLOBAL FOREIGN_KEY_CHECKS = 1;

是否可以暂时禁用约束并删除?

尝试禁用键或

SET FOREIGN_KEY_CHECKS=0;
确保

SET FOREIGN_KEY_CHECKS=1;

在.

之后,不要禁用约束,而是将其永久修改为ON DELETE SET NULL。这将完成类似的事情,您不必打开和关闭钥匙检查。像这样:

ALTER TABLE tablename1 DROP FOREIGN KEY fk_name1; //get rid of current constraints
ALTER TABLE tablename2 DROP FOREIGN KEY fk_name2;

ALTER TABLE tablename1 
  ADD FOREIGN KEY (table2_id) 
        REFERENCES table2(id)
        ON DELETE SET NULL  //add back constraint

ALTER TABLE tablename2 
  ADD FOREIGN KEY (table1_id) 
        REFERENCES table1(id)
        ON DELETE SET NULL //add back other constraint

读取此()和此()。

如果键字段可为空,则您也可以在尝试删除它之前将该值设置为空:

cursor.execute("UPDATE myapp_item SET myapp_style_id = NULL WHERE n = %s", n)
transaction.commit_unless_managed() 

cursor.execute("UPDATE myapp_style SET myapp_item_id = NULL WHERE n = %s", n)
transaction.commit_unless_managed()

cursor.execute("DELETE FROM myapp_item WHERE n = %s", n)
transaction.commit_unless_managed()

cursor.execute("DELETE FROM myapp_style WHERE n = %s", n)
transaction.commit_unless_managed()

要全局关闭外键约束,请执行以下操作:

SET GLOBAL FOREIGN_KEY_CHECKS=0;
完成后记得把它放回去

SET GLOBAL FOREIGN_KEY_CHECKS=1;

警告:只有在执行单用户模式维护时,才应执行此操作。因为这可能导致数据不一致。例如,当您使用mysqldump输出上载大量数据时,这将非常有用。

将外键约束设置为0不是一个好主意,因为如果设置为0,您的数据库将无法确保它不会违反引用完整性。这可能导致数据不准确、误导或不完整

创建外键的原因是:因为子列中的所有值都应与父列中的值相同。如果没有外键约束,则子行的值可能不在父行中,这将导致数据不准确

例如,假设您有一个供学生登录的网站,每个学生都必须注册一个用户帐户。您有一个用户id表,用户id作为主键;和另一个学生帐户表,以学生id作为列。因为每个学生都必须有一个用户id,所以将学生帐户表中的学生id设置为一个外键是有意义的,该外键引用用户id表中的主键用户id。如果没有外键检查,学生可能最终拥有学生id而没有用户id,这意味着学生可以获得一个帐户而不是用户,这是错误的

想象一下,如果它发生在大量数据上。这就是为什么你需要外键检查


最好找出错误的原因。最有可能的情况是,您正在尝试从父行删除,而不从子行删除。在从父行删除之前,请尝试从子行删除

我通常只在需要截断表时才禁用外键约束,因为我一直在回答这个问题,这是为了将来的我:

SET FOREIGN_KEY_CHECKS=0;
TRUNCATE TABLE table;
SET FOREIGN_KEY_CHECKS=1;
在中,可以选择多行,然后单击删除操作。您将进入一个列出删除查询的屏幕。看起来是这样的:

请取消选中“启用外键检查”复选框,然后单击“是”执行这些检查


这将使您能够删除行,即使存在ON delete限制。

一个非常简单的解决方案,包括:

  • 在表中,转到SQL选项卡
  • 编辑要运行的SQL命令后,GO旁边有一个名为“启用外键检查”的复选框
  • 取消选中此复选框并运行SQL。执行后会自动重新检查

要全局关闭外键约束:

SET GLOBAL FOREIGN_KEY_CHECKS = 0;
对于活动外键约束:

cursor.execute("DELETE FROM myapp_item WHERE n = %s", n)
transaction.commit_unless_managed()  #a foreign key constraint fails here

cursor.execute("DELETE FROM myapp_style WHERE n = %s", n)
transaction.commit_unless_managed()
SET GLOBAL FOREIGN_KEY_CHECKS = 1;

对于我来说,只需
设置外键检查=0是不够的。
我仍然有一个
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException

我必须添加
altertablemytable禁用键

因此:


要么我不明白你想做什么,要么你想做的非常非常丑陋。即使你能做到,你可能也不应该。删除并重新应用FK会改变你的db。你试图挑战那些让系统看到某种意义的限制,它根本不考虑FK可能是一件临时的事情,如果它知道了,它会惊慌失措。你试图做的事情很奇怪。但您使用的是哪个数据库?如果您没有禁用约束,而是在DELETE SET NULL中将其永久修改为
?这将完成类似的事情,您不必打开和关闭钥匙检查。@dnagirl:那确实会更好。我该怎么做呢?这是为mysql整体设置的还是仅为该会话设置的?我相信是每个会话设置的,另请注意,对于Innodbi,您可以只禁用单个表的外部密钥检查吗?@Pacerier从阅读中可以看出,您可以,但仅限于单个会话。请注意,更改表可能需要很长时间,最好将
外部密钥检查的服务器全局设置为0,并在脏工作完成后将其放回。此外,它可能会在编写表时被锁定。这不会在更改远程列类型时中断引用吗?(似乎我的客户将一个修改过的临时表重命名为原始表名。)这是我需要知道的,所以这不是一个很好的练习,但这个人的答案应该得分更高……在尝试了“最佳答案”后,这对我有效,但对我无效。也许可以添加对差异的解释。@hexnet区别在于,
SET FOREIGN\u KEY\u CHECKS
只更改当前连接的值,而
SET GLOBAL..
更改所有连接的值,包括将来的连接。如果只在一个窗口中执行
SET FOREIGN..
,然后尝试在另一个窗口(通过不同的连接)中应用该语句,则该值在该窗口中没有更改。使用
GLOBAL
,相同的变量对两个连接都具有相同的值。在播放更大的转储文件(6+GB)时,唯一能帮助我的是,这对我不起作用。当我尝试时,我看到:
错误1228(HY000):V