将Django查询集拆分为子查询集

uqdfh47h  于 2023-05-19  发布在  Go
关注(0)|答案(1)|浏览(120)

我有一个大约有400万个物体的模型。
我想写一个函数,它可以将一个查询集的所有对象分割成长度为100000个对象的子查询集。
例如

all_objects = MyModel.objects.all()

# do the splitting to achieve something like below 
query_set1 = all_objects[0:100000]
query_set2 = all_objects[100000:200000]
# and so on until all objects are within 
query_setn = all_objects[3 900 000:4 000 000]
dpiehjr4

dpiehjr41#

如果在一个burst中处理查询集将不适合内存,您可以使用**.iterator(…)**方法[Django-doc]将其设置为将在内存中加载块的查询集。优点是,您仍然可以一次枚举一个项,因此大多数API就像普通的查询集一样。
因此,您可以使用:

for item in MyModel.objects.iterator(chunk_size=100_000):
    # …
    pass

如果要删除查询中的所有项,可以使用:

to_delete = True
while to_delete:
    to_delete, __ = MyModel.objects.filter(
        pk__in=[item.pk for item in MyModel.objects.only('pk')[:100_000]]
    ).delete()

这不是非常有效,但比逐个枚举每个项要好得多。
我们每次都检查是否删除了任何内容,如果是,则执行另一次运行。
请注意,如果ForeignKey链接到MyModel,即使删除一条MyModel记录也会导致删除其他表中的数百万条记录。因此,虽然我们对MyModel进行切片,但这并不意味着要删除其他模型对象。

相关问题