django:我如何停止保存(使用=)创建新的主键
Posted
技术标签:
【中文标题】django:我如何停止保存(使用=)创建新的主键【英文标题】:django: how do i stop save(using=) from creating new primary key 【发布时间】:2011-05-24 20:55:04 【问题描述】:在 django 中,我想将数据从一个数据库中的相同表复制到另一个数据库中的数据——从“db01”到“默认”。架构是相同的。
>>> a=Household.objects.filter(h_identifier='H122000-48').using('db01')
>>> a[0].pk
>>> u'451465ea-0137-11e0-879a-70f1a16e0f80'
>>> a[0].save(using='default')
>>> b=Household.objects.filter(h_identifier='H122000-48').using('default')
>>> b[0].pk
>>> u'7c2484fe-8641-11e0-b080-00188b4d6b0e'
它可以工作,但是插入到“默认”中的记录的主键与从“db01”中获取的主键不同。为了保持与其他表的完整性,pk 不得更改。 django 文档部分selecting-a-database-for-save 建议,由于实例“a”已经有一个主键,因此在将新记录插入“默认”时将使用相同的主键。我不能让它这样做。
有人知道这是否可以做到吗?提前谢谢!!
(这可能看起来像一个奇怪的设置,但是应用程序白天在断开连接的上网本上独立运行,并且在所有上网本都对接的夜间数据合并到主数据库中。我可以在 mysql 中做得很好,但是如果可能的话,想使用 django ORM。)
【问题讨论】:
这听起来像是底层数据库的问题。 我只用mysql试过这个,所以不能确认你的答案,但这是最可能的原因。 您看到这个问题的RDBMS是什么? mysql 服务器版本:5.1.41-3ubuntu12.10-log (Ubuntu) 【参考方案1】:我知道这是不久前的事情,但我今天遇到了同样的问题 - 根据您使用的密钥判断,您的 id 字段是来自 django_extensions 的 UUIDField 类型?
这有点小问题,因为 pre_save 信号将始终确保替换密钥,无论是否已经存在密钥。对其进行子类化并替换 pre_save 函数可以修复它。
class FixedUUIDField(UUIDField):
def pre_save(self, model_instance, add):
value = super(UUIDField, self).pre_save(model_instance, add)
if self.auto and add and not value:
value = unicode(self.create_uuid())
setattr(model_instance, self.attname, value)
return value
【讨论】:
已经有一段时间了,我采用了不同的方法。虽然我没有对此进行测试,但你在这里所拥有的东西是有道理的,所以我会给你我的投票。谢谢!!【参考方案2】:django docs 建议使用“force_insert”:
第二种选择是使用 保存()到的 force_insert 选项 确保 Django 执行 SQL INSERT:
p = Person(name='Fred') p.save(使用='first') p.save(using='second', force_insert=True) 这将确保 名为 Fred 的人将拥有 两者的主键相同 数据库。如果该主键是 尝试保存时已在使用 到第二个数据库,出错 将被提升。
【讨论】:
"这将确保名为 Fred 的人在两个数据库上具有相同的主键。"仅当数据库不更改 PK 时才成立。 是的,这就是文档所说的,但它不起作用——即使我运行我的示例并使用 force_insert=True。 @ignacio 可能是正确的,因为这是一个 django ORM/mysql 问题。以上是关于django:我如何停止保存(使用=)创建新的主键的主要内容,如果未能解决你的问题,请参考以下文章