我想更新的Django的表格 - 在原始的SQL是这样的:如何用Django“批量更新”?
update tbl_name set name = 'foo' where name = 'bar'
我的第一个结果是这样的 - 但是这讨厌的,不是吗?
list = ModelClass.objects.filter(name = 'bar')
for obj in list:
obj.name = 'foo'
obj.save()
有没有更优雅的方式?
我想更新的Django的表格 - 在原始的SQL是这样的:如何用Django“批量更新”?
update tbl_name set name = 'foo' where name = 'bar'
我的第一个结果是这样的 - 但是这讨厌的,不是吗?
list = ModelClass.objects.filter(name = 'bar')
for obj in list:
obj.name = 'foo'
obj.save()
有没有更优雅的方式?
参考update
功能Django文档中:https://docs.djangoproject.com/en/dev/ref/models/querysets/#update。
总之,你应该能够使用:
ModelClass.objects.filter(name='bar').update(name="foo")
您还可以使用F
对象做这样的事情递增行:
from django.db.models import F
Entry.objects.all().update(n_pingbacks=F('n_pingbacks') + 1)
参见文档:https://docs.djangoproject.com/en/1.9/topics/db/queries/
然而,注意:
ModelClass.save
方法(所以如果你有一些逻辑,它将不会被触发)。考虑使用django-bulk-update
找到here on GitHub。
安装:pip install django-bulk-update
实施:(直接从项目的自述文件中获取代码)
from bulk_update.helper import bulk_update
random_names = ['Walter', 'The Dude', 'Donny', 'Jesus']
people = Person.objects.all()
for person in people:
r = random.randrange(4)
person.name = random_names[r]
bulk_update(people) # updates all columns using the default db
更新:正如马克在评论这是不适合在更新数千行指出一旦。虽然它适用于小批量10至100。适合您的批次大小取决于您的CPU和查询的复杂性。这个工具更像是一辆手推车而不是一辆自卸车。
我试过django-bulk-update,我个人不鼓励使用它。它在内部执行的是创建一个如下所示的单个SQL语句:UPDATE“table”SET“field”= CASE“id”WHEN%s THEN%s WHEN%s THEN%s [...] WHERE id in %s,%s,[...]);.对于少数行(当不需要批量更新时),这种情况是可以的,但有10,000个,查询非常复杂,postgres花费更多的时间在100%理解查询的CPU上,而不是节省写入磁盘的时间。 –
@MarcGarcia好点。我发现许多开发人员在不知道其影响的情况下使用外部库 – Dejell
@MarcGarcia我不同意批量更新不重要,只有在需要数千次更新时才真正需要。由于您提到的原因,使用它一次执行10,000行是不可取的,但使用它同时更新50行比使用50个单独的更新请求触及db要有效得多。 –
您可能正在寻找批量插入。看看http://stackoverflow.com/questions/4294088/accelerate-bulk-insert-using-djangos-orm – Pramod
我不喜欢插入新的数据 - 只需更新现有的。 – Thomas
也许在select_for_update的帮助下? https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.select_for_update –