加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sql – 当使用`delete()`时,如何防止django在内存中加载对象?

发布时间:2020-12-12 06:42:26 所属栏目:MsSql教程 来源:网络整理
导读:我有内存问题,因为看起来Django在使用delete()时将对象加载到内存中.有没有办法阻止Django这样做? 来自Django文档: Django needs to fetch objects into memory to send signals and handle cascades. However,if there are no cascades and no signals,the
我有内存问题,因为看起来Django在使用delete()时将对象加载到内存中.有没有办法阻止Django这样做?

来自Django文档:

Django needs to fetch objects into memory to send signals and handle cascades. However,if there are no cascades and no signals,then Django may take a fast-path and delete objects without fetching into memory. For large deletes this can result in significantly reduced memory usage. The amount of executed queries can be reduced,too.

https://docs.djangoproject.com/en/1.8/ref/models/querysets/#delete

我不使用信号.我在我试图删除的模型上有外键,但我不明白为什么Django需要将对象加载到内存中.它看起来确实如此,因为我的内存随着查询的运行而上升.

解决方法

您可以使用这样的函数迭代大量对象而不使用太多内存:
import gc

def queryset_iterator(qs,batchsize = 500,gc_collect = True):
    iterator = qs.values_list('pk',flat=True).order_by('pk').distinct().iterator()
    eof = False
    while not eof:
        primary_key_buffer = []
        try:
            while len(primary_key_buffer) < batchsize:
                primary_key_buffer.append(iterator.next())
        except StopIteration:
            eof = True
        for obj in qs.filter(pk__in=primary_key_buffer).order_by('pk').iterator():
            yield obj
        if gc_collect:
            gc.collect()

然后,您可以使用该函数迭代要删除的对象:

for obj in queryset_iterator(HugeQueryset.objects.all()):
    obj.delete()

有关更多信息,请查看this blog post.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读