Django 中的批量更新
Vaibhav Vaibhav
2023年1月30日
2021年6月29日
在 Django 中,預設情況下,每個模型都有一個物件管理器。這個管理器可以做很多事情,比如獲取模型例項、過濾模型例項、刪除模型例項。我們甚至可以通過繼承 Django 提供的基礎管理器來建立我們自己的管理器。
現在,我們應用的每個查詢,例如使用 get()
函式檢索單個模型例項或使用 filter()
方法過濾例項,都會命中資料庫一次。這意味著,如果我們有如下 5 個 get()
語句,資料庫將被單獨查詢 5 次。
person = Person.objects.get(id = 1)
person = Person.objects.get(id = 2)
person = Person.objects.get(id = 3)
person = Person.objects.get(id = 4)
person = Person.objects.get(id = 5)
這是一種低效的方法,因為我們正在為單個任務單獨訪問資料庫。如果我們必須為某些模型查詢多個例項或更新多個例項,這種方法會顯著降低我們的應用程式的速度。
為了解決這個問題,Django 有一個內建函式,通常可以用於在一個查詢中更新多個例項。
bulk_update()
Django 中的方法
bulk_update
方法具有三個引數,即 objs
、fields
和 batch_size
。
objs
- 要執行的操作列表fields
- 必須執行查詢的欄位列表batch_size
- 要在單個資料庫查詢中儲存的物件數。它是一個可選引數。預設情況下,更新並儲存所有物件。
考慮一個例子。假設我們有一個 Person
模型,我們必須使用 bulk_update()
方法將所有人員的年齡增加 1
。我們會做以下事情。
在 models.py
中:
from django.db import models
class Person(models.Model):
username = models.CharField(max_length = 200, unique = True)
firstName = models.CharField(max_length = 200)
middleName = models.CharField(max_length = 200)
lastName = models.CharField(max_length = 200)
age = models.IntegerField(default = 0)
在 views.py
中:
people = Person.objects.all()
for person in people:
person.age += 1
Person.objects.bulk_update(people, update_fields = ['age'])
此操作將在單個查詢中更新所有人員的年齡,這是非常有效的。
bulk_update()
方法的缺點
bulk_update()
方法非常好,但並非所有的閃光點都是金子。這種方法有一些缺點。
- 使用
bulk_update()
方法,我們無法更新例項的主鍵。 - 每個模型都有一個
save()
方法。使用bulk_update()
方法時不會呼叫此方法。 - 如果我們要為大量記錄更新許多列,則必須提及批量大小。否則,生成的 SQL 查詢會很長。
Author: Vaibhav Vaibhav