Mam aplikację Django, która odczytuje dane z internetowego interfejsu API i umieszcza je w bazie danych.
Czy istnieje sposób na utworzenie nowego obiektu z trybu, ale zapobieganie zduplikowaniu wyjątku, jeśli obiekt już istnieje?
Innymi słowy, czy istnieje sposób na zapisanie obiektu, ale nie robienie niczego, jeśli już istnieje?
IntegrityError
powoduje przerwanie bieżącej transakcji i nie jest wystarczające.transaction.atomic
(upewnij się złapać poza tenatomic
blok, tzntry: with acomic: create; except IntegrityError
Jest to także trudne, aby upewnić się, że nie złapać. inne błędy integralności niż ta, którą zamierzaszIntegrityError
, moje testy pokazują, że skraca czas wykonywania prawie o połowę, gdy rekord istnieje w porównaniu zget_or_create()
.W Django 1.7 możesz także:
Model.objects.update_or_create()
źródło
Wygląda na to, że w nowszych wersjach Django funkcja save () domyślnie wykonuje UPDATE lub INSERT. Zobacz tutaj .
źródło
Można to osiągnąć za pomocą
Model.objects.get_or_create()
Przykład
obj, created = Person.objects.get_or_create( first_name='John', last_name='Lennon', defaults={'birthday': date(1940, 10, 9)}, )
Wszelkie argumenty słów kluczowych (tutaj first_name i last_name ) przekazane do get_or_create () - z wyjątkiem opcjonalnego o nazwie defaults - zostaną użyte do zapytania w bazie danych (znalezienia obiektu) w bazie danych.
Zwraca krotkę, jeśli obiekt zostanie znaleziony, get_or_create () zwraca krotkę tego obiektu i False.
Uwaga : to samo można osiągnąć za pomocą
try except
instrukcjiPrzykład:
try: obj = Person.objects.get(first_name='John', last_name='Lennon') except Person.DoesNotExist: obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9)) obj.save()
źródło