Duplikate entfernen in Django ORM — mehrere Zeilen
Habe ich ein Modell mit vier Feldern. Wie Entferne ich doppelte Objekte aus meiner Datenbank?
Daniel Roseman Antwort auf diese Frage scheint angebracht, aber ich bin mir nicht sicher, wie Sie Sie verlängern diese sich auf eine situation, wo es vier zu vergleichenden Felder pro Objekt.
Dank,
W.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sollte man nicht tun es oft. Verwenden
unique_together
constraints auf der Datenbank statt.Damit bleibt der Datensatz mit der größten
id
in der DB. Wenn Sie möchten, halten Sie die original-Datensatz (die erste), ändern Sie den code ein bisschen mitmodels.Min
. Sie können auch ganz anderes, wie ERSTELLUNGSDATUM oder so etwas.Zugrunde liegenden SQL-code
Beim kommentieren von django ORM verwendet
GROUP BY
Aussage auf alle Modell verwendeten Felder in der Abfrage. Somit ist die Verwendung von.values()
Methode.GROUP BY
wird die Gruppe alle Einträge mit diesen Werten identisch. Die duplizierten Werte (mehr als einid
fürunique_fields
) werden später herausgefiltert, die inHAVING
- Anweisung generiert.filter()
auf kommentiertenQuerySet
.Doppelte Datensätze werden später gelöscht in der
for
Schleife mit einer Ausnahme auf die häufigsten eine für jede Gruppe.Leer .order_by()
Nur um sicher zu sein, es ist immer ratsam, fügen Sie einen leeren
.order_by()
rufen Sie vor der Aggregation einerQuerySet
.Die Felder für die Bestellung der
QuerySet
sind auch enthalten inGROUP BY
- Anweisung. Leer.order_by()
überschreibt Spalten deklariert Modell istMeta
und im Ergebnis sind Sie nicht in der SQL-Abfrage (z.B. default-Sortierung nach Datum kann ruinieren die Ergebnisse).Können Sie nicht brauchen, um es zu überschreiben auf den gegenwärtigen moment, aber jemand könnte hinzufügen, Standard-Reihenfolge später und deshalb ruinieren Sie Ihre wertvollen löschen-Duplikate code nicht einmal wissen, dass. Ja, ich bin sicher, Sie haben 100% test-coverage...
Fügen Sie einfach leeren
.order_by()
um sicher zu sein. 😉https://docs.djangoproject.com/en/1.11/topics/db/aggregation/#interaction-with-default-ordering-or-order-by
Transaktion
Natürlich sollten Sie überlegen, tun es alle in einer einzigen Transaktion.
https://docs.djangoproject.com/en/1.11/topics/db/transactions/#django.db.transaction.atomic
MyModel.objects.values(*unique_fields)
generiert eine Reihe von Wörterbüchern, mit jedem Wörterbuch in Bezug auf ein Objekt. Aber dann habe ich verloren - was ist mit dem kommentieren zu tun?NameError: name 'duplicate' is not defined
(Python ist3.4, Django1.11). Dies ist, was hat Arbeit für mich:Role.objects.filter(**{field_1: d[field_1], ..., field_n: d[field_n]}).exclude(id=d['max_id']).delete()
. Für einige Grund, warum Sie nicht wollen, entpacken Sie es aus der doppelte Variablen in der filter-Anweisung :/for d in …
stattfor duplicate in …
?duplicate
stattd
. Ich habe versucht, es umzubenennen, um zu überprüfen, dass ich alles richtig machen. Es wirft noch die Ausnahme im ersten Teil des queryset.