基于Django中先前值的快速数据库更新

时间:2016-12-07 16:55:13

标签: django python-3.x django-1.10

我有一个QuerySet,其中包含Page个对象,这些对象具有page_number属性。 QuerySet按page_number排序,因此运行[i.page_number for i in pages_query_set]会返回类似[1,2,3,5,6,10,11,13,16,19,21]之类的内容。我的任务是编写一个移动Page对象以使它们连续的方法:在这个例子中,5的页面将变为4,6将变为5,10将是6,11是7,13是8等等。

这是我的初始解决方案,PageQuerySet类中的一个方法:

def validatePageNumbers(self):
    prev_page = 0
    for page in self:
        if page.page_number > prev_page+1:
            page.page_number = prev_page+1
            page.save()
        prev_page = page.page_number

功能上,它工作正常。但每次调用save()确实会降低速度(可能是因为每次调用数据库查询)。我需要找到一种更快的方法。如果只有一个"差距"在这个序列中,我只是将QuerySet切片并使用sliced_qs.update(page_number=models.F('page_number')-gap)之类的东西,因为我已经看到单个update()比几个save()快得多。但差距很大,而且相当随机。

所以我很困惑。 F个对象似乎不支持此类循环。如果我可以在update()中使用可调用对象,那将会很棒,但我在文档中找不到任何关于它的信息,当我尝试它时它也无效。有没有办法在这里申请update()?或者可能采用其他方法使这种方法更快?

1 个答案:

答案 0 :(得分:0)

解决这个问题和许多其他瓶颈非常简单。

from django.db import transaction

with transaction.atomic():
    #do stuff here

猜测它将所有内容包装到一个事务中,并且仅在数据库中命中一次。 This answer在这里帮了很多忙。

相关问题