development

Django로 '대량 업데이트'하는 방법은 무엇입니까?

big-blog 2020. 6. 29. 07:32
반응형

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()

더 우아한 방법이 있습니까?


UPD 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)

https://docs.djangoproject.com/en/1.9/topics/db/queries/ 설명서를 참조하십시오.

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

  • 이것은 ModelClass.save메소드를 사용하지 않습니다 (따라서 내부에 논리가 있으면 트리거되지 않습니다).
  • 장고 신호가 방출되지 않습니다.

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/dev/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)

If you want to update a collection of rows with different values depending on some condition, you can in best case batch the updates according to values. Let's say you have 1000 rows where you want to set a column to one of X values, then you could prepare the batches beforehand and then only run X update-queries (each essentially having the form of the first example above) + the initial SELECT-query.

If every row requires a unique value there is no way to avoid one query per update. Perhaps look into other architectures like CQRS/Event sourcing if you need performance in this latter case.

참고URL : https://stackoverflow.com/questions/12661253/how-to-bulk-update-with-django

반응형