Django 中的批量更新

Vaibhav Vaibhav 2023年1月30日 2021年6月29日
  1. bulk_update() Django 中的方法
  2. bulk_update() 方法的缺點
Django 中的批量更新

在 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 方法具有三個引數,即 objsfieldsbatch_size

  1. objs - 要執行的操作列表
  2. fields - 必須執行查詢的欄位列表
  3. 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 查詢會很長。
Vaibhav Vaibhav avatar Vaibhav Vaibhav avatar

Vaibhav is an artificial intelligence and cloud computing stan. He likes to build end-to-end full-stack web and mobile applications. Besides computer science and technology, he loves playing cricket and badminton, going on bike rides, and doodling.

LinkedIn GitHub