使用 Django 模型对象在生成器中进行延迟评估

Lazy evaluation in generator with Django model objects

我正在尝试了解如何在 Python 生成器中使用 Django QuerySet 以便它延迟计算。

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

You can evaluate a QuerySet in the following ways:

  • Iteration. A QuerySet is iterable, and it executes its database query the first time you iterate over it.

  • [...]

我有一个像这样的 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())

看起来生成器表达式确实说明了 'iteration',导致 Django 从数据库中检索 QuerySet 中的所有文档。要解决此问题,请使用 iterator() 方法:

(doc.process for doc in Document.objects.iterator())