2017-12-29 3 views
1

Was ich habe eine Liste von Modellobjekten, die ich nicht bulk_create ausgeführt haben auf:Django Kreuzung von nicht commited Modellobjekte und engagierten Modellobjekte

objs = [Model(id=1, field=foo), Model(id=2, field=bar)] 

Was ich möchte, ist mit Model.objects.all() intersect objs zu tun und nur diejenigen Objekte zurückgeben, die noch nicht in der Datenbank sind (basierend auf dem Wert field).

Zum Beispiel, wenn meine Datenbank ist:

[Model(id=3, field=foo)] 

Dann sollte die resultierenden objs sein:

objs = [Model(id=1, field=bar)] 

so etwas wie dies möglich ist?

Edit:

So ein bisschen eine weitere Erklärung:

Was ich tue, das ich einen Import-Befehl haben, dass ich versuche, eine --append Flagge haben enthalten.

Ohne das Flag lösche ich die Tabellen und starte neu.

Mit der Flagge möchte ich eine große Anzahl von Objekten in großen Mengen erstellen (einzelne Erstellung ist viel langsamer - ich habe überprüft), und ich möchte keine Objekte mit den gleichen Feldwerten aber anderen IDs haben.

Ich habe schon versucht, Duplikate nach dem Einfügen zu filtern, aber es ist ziemlich langsam und ich wollte diesen Ansatz testen, um zu sehen, ob es schneller ist.

Die Objekte werden aus CSV-Dateien gelesen, und es ist schneller, eine Liste von Model und dann bulk_create zu erstellen, anstatt create in jeder Zeile auszuführen.

+1

Klingt wie ein [XY-Problem] (https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Was versuchst du eigentlich? – schwobaseggl

+0

Sind Sie ganz sicher, dass Sie nicht 'objs = [Model (id = 2, field = bar)]' wollen? – BorrajaX

+0

Es sieht für mich aus, dass Sie nach einer 'get_or_create'-Funktion suchen. –

Antwort

1

Wir können wohl am besten, dies zu tun, indem man zuerst eine Reihe von Werten, die field Spalte in der Datenbank Konstruktion hat:

field_vals = set(Model.objects.values_list('field', flat=True).distinct()) 

und dann können wir eine Filterung durchführen wie:

filtered_objs = [obj for obj in objs if obj.field not in field_vals]

Durch den Aufbau a set zuerst, führen wir eine einzige Abfrage, erstellen Sie eine set in O (n) (mit n die Nummer Model s in der Datenbank) und filter dann in O (m) (mit m die Anzahl der Objekte in objs). Also ist der Algorithmus O (m + n).

Basierend auf der Frage jedoch sieht es so aus, als könnten Sie wahrscheinlich den Aufwand für die Konstruktion dieser Objekte sparen. Sie können Djangos get_or_create Funktion verwenden.Und verwenden Sie es mögen:

obj, created = Model.objects.get_or_create(field=foo) 

mit obj die beanstandete (entweder abgerufen aus der Datenbank oder in der Datenbank erstellt) und created ein bool ean, die True ist, wenn wir ein neues Objekt zu schaffen hatte.

+0

@schwobaseggl: danke :) –

+0

Während dies eine gültige Antwort ist, würde ich immer noch interessiert sein, was das OP erreichen will, macht das notwendig. Wenn er nur gefilterte Objekte erstellen möchte, muss er nicht zu viele erstellen: – schwobaseggl

+0

Während das funktionieren würde, ist 'bulk_create' für mich viel schneller, als alle Objekte gleichzeitig zu erstellen. – Darkstarone

Verwandte Themen