迭代django对象更新它们的最有效方法是什么?

时间:2015-01-20 02:59:02

标签: python django django-database

所以我有一个更新的查询集

stories = Story.objects.filter(introtext="")
for story in stories:
    #just set it to the first 'sentence'
    story.introtext = story.content[0:(story.content.find('.'))] + ".</p>" 
    story.save()

save()操作完全杀死了性能。在进程列表中,有多个条目用于&#34; ./ manage.py shell&#34;是的,我是通过django shell运行的。

但是,过去我运行的脚本并不需要使用save(),因为它正在改变多个字段。这些脚本非常高效。 我的项目有这个代码,这可能与这些脚本如此优秀的原因有关。

@receiver(signals.m2m_changed, sender=Story.tags.through)
def save_story(sender, instance, action, reverse, model, pk_set, **kwargs):
    instance.save()

有效更新大型查询集(10000+)的最佳方法是什么?

2 个答案:

答案 0 :(得分:4)

只要新的introtext值取决于对象的content字段,您就无法进行批量更新。但是,您可以通过将单个对象包装到事务中来加快保存单个对象的列表:

from django.db import transaction

with  transaction.atomic():
    stories = Story.objects.filter(introtext='')
    for story in stories:
        introtext = story.content[0:(story.content.find('.'))] + ".</p>" 
        Story.objects.filter(pk=story.pk).update(introtext=introtext)

transaction.atomic()会将速度提高一个数量级。

filter(pk=story.pk).update()技巧可以防止在简单pre_save情况下发出的任何post_save / save()信号。这是更新对象的单个字段的officially recommended method

答案 1 :(得分:0)

您可以在update

上使用queryset内置功能

〔实施例:

MyModel.objects.all().update(color=red)

在您的情况下,您需要使用F()(阅读更多here)内置函数来使用实例自己的属性:

from django.db.models import F

stories = Story.objects.filter(introtext__exact='')
stories.update(F('introtext')[0:F('content').find(.)] + ".</p>" )