在Django中使用natural_keys时,如何区分创建和更新?

问题描述

在Django中,我经常将模型夹具从一个数据库复制到另一个数据库。我的模型在序列化过程中使用natural_keys(尽管我不确定这是否相关)。如何确保一个数据库中已更新的实例没有插入到另一数据库中?

考虑以下代码

models.py:

class AuthorManager(models.Manager):
  def get_by_natural_key(self,name):
    return self.get(name=name)

class Author(models.Model):
  objects = AuthorManager()
  name = models.CharField(max_length=100)
  def natural_key(self):
    return (self.name,)

现在,如果我创建一个名为“威廉·莎士比亚”的作者,并通过python manage.py dumpdata --natural_keys将其转储到固定装置中,我将得到以下文件

[
  {
    "model": "myapp.author","fields": {
      "name": "Wiliam Shakespeare"
    }
  }
]

我可以将其加载到另一个数据库中,它将创建一个名为“威廉·莎士比亚”的作者。

但是 ,如果我在原始数据库中将该作者重命名为“比尔·莎士比亚”,并重新创建固定装置并将其加载到另一个数据库中,则它将创建另一个 new 作者名为“比尔·莎士比亚”,而不是更新现有 Author的名字。

关于如何解决这个问题的任何想法?

解决方法

您使用的固定装置不是用于同步数据库。它用于填充空数据库。特别地,“删除”不能在固定装置中表达。基于自然键的更新可以表示为插入+删除。

现在您可以通过不使用自然键来解决此问题,但是数据库之间的主键必须相同。如果目标数据库从其他来源接收到插入,则这是一个问题,因为更新将在错误的对象上进行。

简而言之:使用同步/复制工具同步数据库,使用夹具进行迁移和测试。尝试使用灯具进行同步容易出错。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...