在带有Django模型对象的生成器中的惰性评估

问题描述 投票:0回答:1

[我试图了解如何在Python生成器中使用Django QuerySet,以便其懒惰地求值。

该文档没有明确提及生成器,这似乎是(或多或少)唯一相关的评论,但它并不能澄清我的问题:

您可以通过以下方式评估QuerySet:

  • 迭代。 QuerySet是可迭代的,并且在您第一次对其进行迭代时会执行其数据库查询。

  • [...]

我有这样的Django模型:

class Document(models.Model):
    text = [...]

    @cached_property
    def process(self):
        [...]

现在我尝试这个:

processed = (doc.process for doc in Document.objects.all())

但是,我注意到这立即为所有对象触发了process()方法,这导致内存消耗激增。

逐步调查:

docs = Document.objects.all()
test = (doc for doc in docs)

Document.objects.all()不会触发任何评估,它只会按预期方式创建QuerySet。但是,第二行(test)已经将整个文档集加载到内存中,因此,如上所示的process()调用显然不是问题。

在我看来,从QuerySet创建生成器理解已经触发了Django数据库调用。如果真是这样,我如何才能正确实现我最初想要的目标,即像这样懒惰地评估发电机:

(doc.process for doc in Document.objects.all())
python django generator lazy-evaluation
1个回答
0
投票

似乎生成器表达式实际上确实说明了“迭代”,导致Django从数据库的QuerySet中检索所有文档。要解决此问题,请使用iterator()方法:

(doc.process for doc in Document.objects.iterator())
© www.soinside.com 2019 - 2024. All rights reserved.