【问题标题】:Lazy evaluation in generator with Django model objects使用 Django 模型对象在生成器中进行延迟评估
【发布时间】:2020-02-10 10:04:20
【问题描述】:

我正在尝试了解如何在 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】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-14
      • 2018-08-12
      • 1970-01-01
      • 2014-12-22
      • 1970-01-01
      • 2021-05-17
      相关资源
      最近更新 更多