Django : loaddata 更新数据
Django : loaddata to update data
我有一个夹具 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: Problem installing fixture .....\seed_data.json
Could not load catalog.Product(pk=2): column name is not unique
所以在添加一些数据时没有问题,但是在尝试删除一些数据时,与主键发生冲突。
我怎样才能实现我想要做的事情?
夹具仅适用于全新数据库实例的初始数据,例如 运行 测试时。要修改现有数据,请使用迁移。
这么多年过去了,带着一个悬而未决的问题,我想补充一些东西,因为我也确实为固定装置而苦恼。
对于修改现有数据,正如@Thomas所说,最好使用Django data migrations。
虽然刚接触 Django,您可能会想使用固定装置来更新一些基本数据。同样,不推荐这样做,但解释可以做什么也无妨。因此,使用示例:
{"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
的对象)上已经存在的主键来更新对象。您不能只用夹具删除带有 pk = 3
的对象。如果你这样做了,那么上面更新的固定装置就可以工作了。
这里有一些规则可以提供帮助。
修改夹具并对其调用 loaddata
时可以做什么:
- 更新数据(只要遵守唯一性约束)。 Django 将使用
pk
来匹配对象,并且会在不调用任何 pre_save
函数的情况下替换之前的对象(所以这是不推荐使用它的另一个原因)
- 创建数据(使用与之前相同的约束)
修改夹具并对其调用 loaddata
时不能执行的操作:
- 您不能显式删除具有夹具的对象。由于您要删除的对象的
pk
不在文件中,因此它将原样保留在数据库中。所以你必须手动删除它。
我有一个夹具 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: Problem installing fixture .....\seed_data.json
Could not load catalog.Product(pk=2): column name is not unique
所以在添加一些数据时没有问题,但是在尝试删除一些数据时,与主键发生冲突。
我怎样才能实现我想要做的事情?
夹具仅适用于全新数据库实例的初始数据,例如 运行 测试时。要修改现有数据,请使用迁移。
这么多年过去了,带着一个悬而未决的问题,我想补充一些东西,因为我也确实为固定装置而苦恼。
对于修改现有数据,正如@Thomas所说,最好使用Django data migrations。
虽然刚接触 Django,您可能会想使用固定装置来更新一些基本数据。同样,不推荐这样做,但解释可以做什么也无妨。因此,使用示例:
{"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
的对象)上已经存在的主键来更新对象。您不能只用夹具删除带有 pk = 3
的对象。如果你这样做了,那么上面更新的固定装置就可以工作了。
这里有一些规则可以提供帮助。
修改夹具并对其调用 loaddata
时可以做什么:
- 更新数据(只要遵守唯一性约束)。 Django 将使用
pk
来匹配对象,并且会在不调用任何pre_save
函数的情况下替换之前的对象(所以这是不推荐使用它的另一个原因) - 创建数据(使用与之前相同的约束)
修改夹具并对其调用 loaddata
时不能执行的操作:
- 您不能显式删除具有夹具的对象。由于您要删除的对象的
pk
不在文件中,因此它将原样保留在数据库中。所以你必须手动删除它。