如何从内存中删除Django的BinaryField?

时间:2017-04-12 14:20:05

标签: python django memory deferred

我有一个带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)

1 个答案:

答案 0 :(得分:1)

像这样使用iterator

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

评估QuerySet(通过执行查询)并在结果上返回一个迭代器(参见PEP 234)。 QuerySet通常在内部缓存其结果,以便重复的计算不会导致其他查询。相反,iterator()将直接读取结果,而不在QuerySet级别执行任何缓存(在内部,默认迭代器调用iterator()并缓存返回值)。对于返回大量只需要访问一次的大量对象的QuerySet,这可以提高性能并显着降低内存。