如何在Django模型中原子地查询和更新某个记录集?

13 浏览
0 Comments

如何在Django模型中原子地查询和更新某个记录集?

我在django模型中有一些记录,每次我都想查询和更新其中的一些记录。\n如何以原子方式执行此操作?\n

def queryAndUpdate(count):
    entries = Model.objects.filter(...)[:count]
    for entry in entries:
        entry.count = F('count') + 1
        entry.save()
    return entries

\n我尝试了QuerySet.select_for_update(),但它失败了。

0
0 Comments

问题的原因是在Django中对模型进行查询和更新时,无法原子地使用切片(slice)操作。具体地说,如果我们想要对一个查询集(QuerySet)进行切片操作并进行更新,那么我们需要另外找到一种解决方法。

为了解决这个问题,我们可以使用以下方法来查询和更新模型的记录集(record set):

Model.objects.filter(...).update(count=F('count') + 1)

这里是官方文档的链接:[https://docs.djangoproject.com/en/dev/topics/db/queries/#updating-multiple-objects-at-once](https://docs.djangoproject.com/en/dev/topics/db/queries/#updating-multiple-objects-at-once)。

如果我们想要限制查询集的大小为100,我们可以使用如下方式:

Model.objects.filter(...)[:100]

这样的查询语句会被转化为`SELECT ... LIMIT 100`,所以我们不需要担心性能问题。这里有另一个关于这个问题的问题:[https://stackoverflow.com/questions/6574003](https://stackoverflow.com/questions/6574003)。

返回值的类型是``,与`Model.objects.filter(...)`的返回值相同,所以我们也可以使用`Model.objects.filter(...)[:100].update(...)`。

但是这种方法无法对查询集进行切片操作,而且`update`方法只返回查询集的大小。所以在对查询集进行切片后,无法使用`update`方法。

通过以上方法,我们可以解决在Django中原子地查询和更新模型记录集的问题。

0