Django: 使用loaddata更新数据

15

我有一个名为seed_data.json的固定配置文件,其中包含我的初始数据。

有时我会向这个配置文件中添加新数据并重新加载它,这样可以正确更新我的数据。

但是,现在我想要从中删除一些数据。因此,我修改了我的seed_data.json,例如,我原本像这样:

{"fields": {"name": "Field 0"},"model": "catalog.product","pk": 1},
{"fields": {"name": "Field 1"},"model": "catalog.product","pk": 2},
{"fields": {"name": "Field 2"},"model": "catalog.product","pk": 3},
# ...

那变成了:

{"fields": {"name": "Field 1"},"model": "catalog.product","pk": 1},
{"fields": {"name": "Field 2"},"model": "catalog.product","pk": 2},
# ...

但我得到了:

django.db.utils.IntegrityError: 安装夹具时出现问题.....\seed_data.json

无法加载catalog.Product(pk=2):列名不唯一

因此,在添加一些数据时没有问题,但在尝试删除一些数据时,会出现与主键的冲突。

我该如何实现我想要做的事情?

2个回答

8

经过那么多年的努力,却仍有一个未解决的问题,这让我想要添加一些东西,因为我也曾苦于fixtures。

对于修改现有数据,正如@Thomas所说,最好使用Django数据迁移

然而,当初接触Django时,你可能会想要使用fixtures来更新一些基础数据。再次强调,这并不被推荐,但解释一下可以做些什么也无妨。所以,我们将使用以下示例:

{"fields": {"name": "Field 0"},"model": "catalog.product","pk": 1},
{"fields": {"name": "Field 1"},"model": "catalog.product","pk": 2},
{"fields": {"name": "Field 2"},"model": "catalog.product","pk": 3},
# ...

那变成了:

{"fields": {"name": "Field 1"},"model": "catalog.product","pk": 1},
{"fields": {"name": "Field 2"},"model": "catalog.product","pk": 2},
# ...

这里的问题实际上是尝试使用已经存在于另一个对象中的主键(pk = 3)来更新对象。您不能只使用fixture删除pk = 3的对象。但是如果手动删除它,那么上面更新后的fixture将起作用。

以下是一些有用的规则:

当修改fixture并在其上调用loaddata时,您可以执行以下操作:

  • 更新数据(只要它遵守唯一性约束)。 Django将使用pk匹配对象,并替换以前的对象,而不调用任何pre_save函数(因此这也是为什么不建议使用它的另一个原因)
  • 创建数据(具有与之前相同的约束条件)

当修改fixture并在其上调用loaddata时,您不能执行以下操作:

  • 您不能使用fixture显式地删除对象。由于要删除的对象的pk不会在文件中,它将保持在数据库中。因此您必须手动删除它。

5

Fixtures(夹具)仅用于完全新的数据库实例的初始数据,例如运行测试时。要修改现有数据,请使用迁移。


那么,为了实际更改应用程序的初始数据,我需要清除我的数据库吗? - Ellone
是的,但是有时候当我们更新一个应用程序时,初始数据会发生一些改变。而清除数据库也会删除非初值的数据。当然我可以使用管理员界面,但我想保持记录上的干净的主键。 - Ellone
2
不,你不使用管理员。你要像我说的那样编写数据迁移。 - Tomas Walch
3
好的,我认为迁移是用于模型变更等方面的。我会研究数据迁移。 - Ellone
不,这只是用于表模式的,就像@Ellone所说的。你无法使用它更新内部数据。 - ThePhi
1
@ThePhi 不是这样的,请阅读文档以了解迁移如何帮助迁移数据以及模式 https://docs.djangoproject.com/en/3.2/howto/writing-migrations/ - harschware

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接