Django의 대량 업데이트
Django에서는 기본적으로 모든 모델에objects
관리자가 있습니다. 이 관리자는 모델 인스턴스 가져 오기, 모델 인스턴스 필터링, 모델 인스턴스 삭제와 같은 많은 작업을 수행 할 수 있습니다. Django에서 제공하는 기본 관리자를 상속하여 자체 관리자를 만들 수도 있습니다.
이제get()
함수를 사용하여 단일 모델 인스턴스를 검색하거나filter()
메소드를 사용하여 인스턴스를 필터링하는 것과 같이 적용하는 모든 단일 쿼리가 데이터베이스를 한 번 조회합니다. 이는 다음과 같이 다섯 개의get()
문이있는 경우 데이터베이스가 개별적으로 다섯 번 쿼리된다는 것을 의미합니다.
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에는 일반적으로 하나의 쿼리에서 여러 인스턴스를 업데이트하는 데 사용할 수있는 내장 함수가 있습니다.
Django의bulk_update()
메서드
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 쿼리가 매우 길어집니다.