장고로 테이블을 업데이트하고 싶습니다. 원시 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")
이 링크를 참조하여 대량 업데이트 및 작성에 대한 자세한 정보를 얻을 수 있습니다.
대량 업데이트 및 생성