[我试图了解如何在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())
似乎生成器表达式实际上确实说明了“迭代”,导致Django从数据库的QuerySet中检索所有文档。要解决此问题,请使用iterator()
方法:
(doc.process for doc in Document.objects.iterator())