我希望标准化我的数据库中的字段。如何执行以下操作,其中字段具有FK约束:
在django:
Platform.objects.filter(name='ITUNES').update(name='iTunes')
# gives FK error
在mysql中:
update main_platform set name='iTunes' where name='ITUNES'
# Cannot delete or update a parent row: a foreign key constraint fails (`avails`.`main_credit`, CONSTRAINT `main_credit_ibfk_3` FOREIGN KEY (`platform_id`) REFERENCES `main_platform` (`name`))
对此有什么解决方法?
请注意,我不打算添加其他字段,例如ID字段,FK永远不会更改,我只对更新现有字段感兴趣。
我对平台的当前表格是:
CREATE TABLE `main_platform` (
`name` varchar(20) NOT NULL,
`guid` varchar(40) DEFAULT NULL,
PRIMARY KEY (`name`),
KEY `guid` (`guid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
答案 0 :(得分:1)
这看起来更像是一个SQL问题。
您有name
作为主键,因此如果您尝试在引用它的链接表中有行时直接更新它,那么事情肯定会破坏。
如果您不打算修改表格以使用数字ID作为主键(这是一个非常好的主意),那么我能看到的最佳实际选项是添加一个新行main_platform
使用新名称字段(iTunes vs ITUNES),然后迁移任何相关数据以指向该新行,最后删除旧行。
请参阅this回答,以便更深入地了解问题,并希望被说服并使用数字ID作为主键。
答案 1 :(得分:1)
请务必先关闭您的应用程序,因为此设置是系统范围的。
from django.db import connection
assert connection.vendor == 'mysql'
cursor = connection.cursor()
cursor.execute("SET FOREIGN_KEY_CHECKS = 0")
try:
# do your data migration here
finally:
cursor.execute("SET FOREIGN_KEY_CHECKS = 1")
来自文档的警告:
添加到表中的行虽然不会验证
foreign_key_checks = 0
的一致性
您可能还想查看this question。
但是,你真的应该使用数字ID。