【问题标题】:How to remove Django`s BinaryField from memory?如何从内存中删除 Django 的 BinaryField?
【发布时间】:2017-04-12 14:20:04
【问题描述】:

我有一个带有 BinaryField 的 Django 模型:

class MyData(models.Model):
    someData = models.CharField()
    data = models.BinaryField()

在我的应用程序中,我需要遍历大量行。当然我将二进制字段标记为延迟:

myDataList = MyData.objects().filter(...).defer('data')
for myData in myDataList:
    doSmthWithData(myData.data)
    ...

初始请求的结果需要少量内存。但是,当我遍历查询集时,我从数据库中获取二进制数据。由于二进制字段的大小,内存很快就会耗尽。

我们可以做一个技巧来释放内存——在循环结束时将data 设置为NonemyData = None。但是在这种情况下要修改和保存实体我需要从数据库中再次查询它,否则二进制数据会丢失。

我们还有其他方法可以从内存中删除二进制数据吗?比如:set_defer(myData.data)

【问题讨论】:

    标签: python django memory deferred


    【解决方案1】:

    像这样使用iterator

    myDataList = MyData.objects().filter(...).defer('data')
    for myData in myDataList.iterator():
        doSmthWithData(myData.data)
    

    评估 QuerySet(通过执行查询)并在结果上返回一个迭代器(参见 PEP 234)。 QuerySet 通常在内部缓存其结果,以便重复评估不会导致额外的查询。相比之下,iterator() 将直接读取结果,而不在 QuerySet 级别进行任何缓存(在内部,默认迭代器调用 iterator() 并缓存返回值)。对于返回大量对象且您只需要访问一次的 QuerySet,这可以带来更好的性能并显着减少内存。

    【讨论】:

      猜你喜欢
      • 2016-03-19
      • 2019-05-27
      • 1970-01-01
      • 2019-01-21
      • 1970-01-01
      • 1970-01-01
      • 2019-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多