更新主键 Django MySQL

Posted

技术标签:

【中文标题】更新主键 Django MySQL【英文标题】:Update primary key Django MySQL 【发布时间】:2015-06-21 19:58:19 【问题描述】:

我尝试使用 .save() 方法更新 Django 中的 PK,但是当我保存对象时,Django 使用相同的数据但不同的 PK 复制对象。例如:

from gestion_empleados.Models import Empleados
>>> e = Empleados.objects.get(pk="56789034U")
>>> e.pk
u'56789034U'
>>> e.pk = "11111111L"
>>> e.save()
>>> e.pk
'11111111L'
>>> e2 = Empleados.objects.get(pk="56789034U")
>>> e2
<Empleados: Juan 56789034U>
>>> e
<Empleados: Juan 11111111L>

对象相同,PK不同,我想更改PK而不复制对象。

有什么解决办法吗?谢谢!

【问题讨论】:

【参考方案1】:

我认为 Django 不允许您更改对象的主键。您可能必须删除原始对象。

e2.delete()

根据 Django 文档

主键字段是只读的。如果您更改现有对象的主键值并保存它,则会在旧对象旁边创建一个新对象。

Django Docs

【讨论】:

我想删除原始对象但奇怪的是django不允许更新PK,谢谢!【参考方案2】:

Django 的Model.save() 方法依赖于您的数据库中是否已经存在具有相同PK 的行来决定它是否应该发出INSERTUPDATE 查询。

作为更一般的规则:虽然技术上可以在 SQL 级别修改 PK,但这不一定是个好主意,因为这意味着您必须更新所有相关行所有相关的表格(好吧,在技术上仍然可行,但就我而言,这确实不是一个理智的想法),并警告所有应用程序也取决于此更改的 PK - 然后祝你好运。长话短说:将 PK 视为不可变总是更安全(这就是为什么 SQL 世界中有相当多的人喜欢代理主键,即使存在看似明显的自然主键)。

【讨论】:

这里的问题是 Django 试图与 DB 无关,因此不支持 CASCADE UPDATE,这是更新自然键的明智方法。 @DylanYoung 就我而言,唯一“理智”的方法是拥有不可变、不可重用的主键。尝试对真实大小的数据集进行级联更新,您会发现为什么它不是一个可行的解决方案。此外,它只会更新数据库内容本身,而不是依赖于它的任何外部数据(并且外部应用程序取决于您的数据库 pks 是一种非常常见的情况)。 感谢您的星星,您没有管理需要迁移主键的数据库:) 仅供参考:我知道的每个数据库都重用串行主键。使用 UUID 会对性能产生重大影响。这是理智的吗? 除了有问题的 dbms (forums.mysql.com/read.php?10,643901,643904#msg-643904),我从未见过 dbms 重复使用串行 pks(至少在没有人弄乱计数器的情况下不会)。我不必管理需要迁移 pks 的数据库的原因是我确保我没有任何理由这样做 - 不再是这样(曾经在这里,做过,现在我知道更好了)。 【参考方案3】:

首先,您应该确保主键为“11111111L”的对象已添加到您的表中。可能会按照以下方式做一些事情:

e3 = Empleados.objects.get(pk="11111111L")

然后确保 e3 包含 .一旦你确认它在那里,那么你可以使用以下语句来删除主键为“56789034U”的对象(假设你保留 e2):

e2.delete()

【讨论】:

以上是关于更新主键 Django MySQL的主要内容,如果未能解决你的问题,请参考以下文章

mysql 存储过程 若主键冲突则更新,不冲突则插入数据

Mysql——UPDATE操作对应的undo日志

WAMP 更新和迁移后,mysql 表没有结构/主键

mysql insert插入时实现如果数据表中主键重复则更新,没有重复则插入的四种方法

Mysql实现无插入有更新(不知主键的情况下)

谈谈mysql的主键和外键