[django] Django로 ‘대량 업데이트’하는 방법은 무엇입니까?

장고로 테이블을 업데이트하고 싶습니다. 원시 SQL에서 이와 같은 것입니다.

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 2.2 버전에는 이제 bulk_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)

설명서를 참조하십시오 .

그러나 다음 사항에 유의하십시오.

  • 이것은 ModelClass.save메소드를 사용하지 않습니다 (따라서 내부에 논리가 있으면 트리거되지 않습니다).
  • 장고 신호가 방출되지 않습니다.
  • .update()슬라이스 된 QuerySet에 대해 수행 할 수 없으며 원래 QuerySet에 있어야하므로 .filter()and .exclude()메소드 에 의존해야 합니다.

답변

GitHubdjango-bulk-update 에서 here 사용을 고려 하십시오 .

설치: pip install django-bulk-update

구현 : (프로젝트 ReadMe 파일에서 직접 가져온 코드)

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

업데이트 : Marc는 의견에서 지적했듯이 한 번에 수천 행을 업데이트하는 데 적합하지 않습니다. 더 작은 배치 10 ~ 100에 적합하지만. 적합한 배치 크기는 CPU 및 쿼리 복잡성에 따라 다릅니다. 이 도구는 덤프 트럭보다 휠 배로 우와 비슷합니다.


답변

Django 2.2 버전에는 이제 bulk_update방법이 있습니다 ( 릴리스 노트 ).

https://docs.djangoproject.com/en/stable/ref/models/querysets/#bulk-update

예:

# get a pk: record dictionary of existing records
updates = YourModel.objects.filter(...).in_bulk()
....
# do something with the updates dict
....
if hasattr(YourModel.objects, 'bulk_update') and updates:
    # Use the new method
    YourModel.objects.bulk_update(updates.values(), [list the fields to update], batch_size=100)
else:
    # The old & slow way
    with transaction.atomic():
        for obj in updates.values():
            obj.save(update_fields=[list the fields to update])


답변

rows 컬렉션에 동일한 값설정하려면 update () 메서드를 쿼리 용어와 함께 사용하여 하나의 쿼리에서 모든 행을 업데이트 할 수 있습니다.

some_list = ModelClass.objects.filter(some condition).values('id')
ModelClass.objects.filter(pk__in=some_list).update(foo=bar)

일부 조건에 따라 다른 값으로 행 모음업데이트 하려는 경우 에 따라 업데이트를 일괄 처리 할 수 ​​있습니다. 열을 X 값 중 하나로 설정하려는 1000 개의 행이 있고 사전에 배치를 준비한 다음 X 업데이트 쿼리 (각각 위의 첫 번째 예의 형식을 가짐) + 초기 SELECT 만 실행할 수 있다고 가정 해 봅시다. -질문.

모든 행에 고유 한 값필요한 경우 업데이트 당 하나의 쿼리를 피할 수있는 방법이 없습니다. 후자의 경우 성능이 필요한 경우 CQRS / 이벤트 소싱과 같은 다른 아키텍처를 살펴볼 수 있습니다.


답변

IT는 테이블에서 업데이트 된 개체 수를 반환합니다.

update_counts = ModelClass.objects.filter(name='bar').update(name="foo")

이 링크를 참조하여 대량 업데이트 및 작성에 대한 자세한 정보를 얻을 수 있습니다.
대량 업데이트 및 생성


답변