有没有可能使用F表达式来执行此操作?一些如何减少命中数据库?
# 1st way hits DB twice per object
def something():
pks = [4, 2, 1, 3, 0]
for i in range(len(pks)):
mymodel.objects.get(pk=pks[i]).update(attr=i)
# 2nd way hits DB once per obj and once for the queryset
def something():
pks = [4, 2, 1, 3, 0]
order = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(pks)])
query = mymodel.objects.filter(pk__in=pks).order_by(order)
for i in range(len(query)):
query[i].attr = i
query[i].save()
编辑以使变量一致。
最佳答案
通常应避免进行多个数据库查询而不是一个大型查询。但是,您的情况似乎是一个异常(exception)。 (注意:我是根据所提供的信息做出这个答案的。请不要编辑您的问题说我的意思是……。)
无论您有多少记录,以下查询都将非常快,因为它是从主键中检索单个项目。所有RDBMS的设计都可以很好地处理此问题。
mymodel.objects.get(pk=a[i])
如何通过这种方式使您的函数更高效:
def something():
pks = [4, 2, 1, 3, 0]
for i in range(len(a)):
mymodel.objects.filter(pk=a[i]).update(attr=i)
现在,它仅对每个对象命中一次DB。上面的查询只是翻译成
UPDATE mapp_mymodel SET attr=i where pk=1