Chciałbym zaktualizować tabelę za pomocą Django - coś takiego w surowym SQL:
update tbl_name set name = 'foo' where name = 'bar'
Mój pierwszy wynik jest taki - ale to paskudne, prawda?
list = ModelClass.objects.filter(name = 'bar')
for obj in list:
obj.name = 'foo'
obj.save()
Czy jest bardziej elegancki sposób?
django
django-models
Thomas Schwärzl
źródło
źródło
ModelClass
podejściu? NastępnieOdpowiedzi:
Aktualizacja:
Wersja Django 2.2 ma teraz bulk_update .
Stara odpowiedź:
Zapoznaj się z następującą sekcją dokumentacji django
Krótko mówiąc, powinieneś być w stanie użyć:
Możesz także używać
F
obiektów do wykonywania takich czynności, jak zwiększanie liczby wierszy:Zobacz dokumentację .
Należy jednak pamiętać, że:
ModelClass.save
metody (więc jeśli masz w sobie jakąś logikę, nie zostanie ona uruchomiona)..update()
na podzielonym zestawie QuerySet, musi on znajdować się na oryginalnym zestawie QuerySet, więc musisz oprzeć się na metodach.filter()
i.exclude()
.źródło
save()
,DateTimeField
Polaauto_now=True
( „modyfikowane” kolumny) nie zostaną zaktualizowane.ModelClass.objects.filter(name = 'bar').update(name="foo")
nie spełnia celu zbiorczej aktualizacji, jeśli mam różne dane dla różnych identyfikatorów, jak mogę to zrobić bez używania pętli?Entry.objects.all().update(title=F('blog__title'))
. Dokumenty zawierają małą wzmiankę o tym. Jeśli chcesz pobrać dane z innego modelu, aby zaktualizować swoje wpisy, musisz uruchomić pętlę forRozważ użycie
django-bulk-update
znalezionego tutaj na GitHub .Zainstalować:
pip install django-bulk-update
Implement: (kod pobrany bezpośrednio z pliku ReadMe projektów)
Aktualizacja: Jak podkreśla Marc w komentarzach, nie nadaje się do jednoczesnej aktualizacji tysięcy wierszy. Chociaż nadaje się do mniejszych partii od 10 do 100. Wielkość partii, która jest odpowiednia dla Ciebie, zależy od procesora i złożoności zapytań. To narzędzie bardziej przypomina taczkę niż wywrotkę.
źródło
Wersja Django 2.2 ma teraz
bulk_update
metodę ( uwagi do wydania ).https://docs.djangoproject.com/en/stable/ref/models/querysets/#bulk-update
Przykład:
źródło
Jeśli chcesz ustawić tę samą wartość w zbiorze wierszy , możesz użyć metody update () w połączeniu z dowolnym terminem zapytania, aby zaktualizować wszystkie wiersze w jednym zapytaniu:
Jeśli chcesz zaktualizować kolekcję wierszy z różnymi wartościami w zależności od określonego warunku, w najlepszym przypadku możesz grupować aktualizacje według wartości. Załóżmy, że masz 1000 wierszy, w których chcesz ustawić kolumnę na jedną z wartości X, wtedy możesz wcześniej przygotować partie, a następnie uruchomić tylko X zapytań aktualizujących (każdy zasadniczo ma postać pierwszego przykładu powyżej) + początkowy SELECT -pytanie.
Jeśli każdy wiersz wymaga unikalnej wartości, nie ma możliwości uniknięcia jednego zapytania na aktualizację. Być może przyjrzyj się innym architekturom, takim jak CQRS / Event sourcing, jeśli potrzebujesz wydajności w tym drugim przypadku.
źródło
Możesz odesłać ten link, aby uzyskać więcej informacji na temat zbiorczej aktualizacji i tworzenia. Zbiorcza aktualizacja i tworzenie
źródło