【发布时间】:2016-08-15 16:57:41
【问题描述】:
我有一个 Django 模型,它的表中有数百万条记录。我正在尝试在 shell 中对表中的所有记录进行一些紧急维护,但我无法在不完全耗尽系统内存的情况下执行 MyModel.objects.all()。
即使是 pass 也会导致调用 OOM 杀手,从而杀死我的进程:
for ii in MyModel.objects.all():
pass
原因是因为 Django 的 QuerySet 正在尝试建立它的“结果缓存”,方法是建立一个列表,其中包含 所有 我的记录,这里:
# django/db/models/query.py
def _fetch_all(self):
if self._result_cache is None:
self._result_cache = list(self.iterator()) # <<<< this guy!
if self._prefetch_related_lookups and not self._prefetch_done:
self._prefetch_related_objects()
但我的机器无法将整个列表保存在内存中。
当然,在如此大的表上迭代 .all() 在实际应用中是一个糟糕的想法,因此这个问题的范围相当有限(维护活动),但它确实会不时出现。
【问题讨论】: