【问题标题】:Django ORM bulk_create 1:1 related modelsDjango ORM bulk_create 1:1 相关模型
【发布时间】:2019-05-01 05:34:34
【问题描述】:

我看到有人问过类似的问题,但提供的答案含糊不清,因此我将不胜感激。

我想对一些相关的 1:1 对象进行批量创建。

我希望我能做这样的事情:

class A(models.Model):

class B(models.Model):
    A = models.ForeignKey(A)

all_a = []
all_b = []
for i in range(10000):
    new_a = A()
    new_b = B(A=new_a)
    all_a.append(new_a)
    all_b.append(new_b)

with transaction.atomic():
    A.objects.bulk_create(all_a)
    B.objects.bulk_create(all_b)

但我猜测 A 模型需要写入数据库,并返回实际 PK 并与 B 模型关联,然后才能写入它们。

有没有人对如何有效地做到这一点有好的建议? 提前致谢

【问题讨论】:

  • 您使用的是什么数据库? PostgreSQL 有一个很好的解决方案。
  • 使用 Postgres,但可能会在某个阶段转移到像 TimeScale 这样的 TS 数据库。

标签: django python-3.x django-orm


【解决方案1】:

是的,您需要事先创建 A 实例。试试这样:

all_a = []
all_b = []
new_a_list = []

for i in range(10000):
    new_a = A()
    all_a.append(new_a)
with transaction.atomic():
    new_a_list = A.objects.bulk_create(all_a)

for new_a in new_a_list:
    new_b = B(A=new_a)
    all_b.append(new_b)

with transaction.atomic():
    B.objects.bulk_create(all_b)

【讨论】:

  • 能否保证从第一个bulk_create返回的set的顺序匹配a和b记录?
  • 据我测试,是的。
  • 它按照列表作为参数传递的顺序进行批量创建。
【解决方案2】:

在 PostgreSQL 上这很简单,因为 bulk_create() 对应于 A will populate 每个对象的 pk

with transaction.atomic():
    all_a = [A() for _ in range(1000)]
    A.objects.bulk_create(all_a)

    all_b = [B(A=new_A) for new_a in all_a]
    B.objects.bulk_create(all_b)

在其他数据库上这会更棘手,因为bulk_create() doesn't get the ids 是新创建的对象。

如果模型的主键是 AutoField,它不会像 save() 那样检索和设置主键属性,除非数据库后端支持它(目前是 PostgreSQL)。

【讨论】:

    猜你喜欢
    • 2015-01-21
    • 2015-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    • 2016-05-21
    • 2019-08-11
    相关资源
    最近更新 更多