Django ORM: Caching und Manipulation von ForeignKey-Objekten

7

Betrachte das folgende Skelett einer models.py für ein Weltraum-Eroberungsspiel:

%Vor%

Ich habe viele solcher Datenmodelle für ein Projekt, an dem ich gerade arbeite, und ich ändere den Zustand des Spiels aufgrund einiger komplizierter Interaktionen zwischen verschiedenen Datenobjekten. Ich möchte viele unnötige Aufrufe an die Datenbank vermeiden, also mache ich einmal pro Runde etwas wie

  1. Abfrage aller Flotten, Planeten und anderer Objekte aus der Datenbank und Zwischenspeicherung als Python-Objekte
  2. Verarbeitet die Spielobjekte und löst den Status des Spiels auf
  3. Speichern Sie sie wieder in der Datenbank

Dieses Modell scheint bei der Verwendung von ForeignKey-Objekten vollständig zu zerfallen. Zum Beispiel, wenn eine neue Flotte einen Planeten verlässt, habe ich eine Linie, die ungefähr so ​​aussieht:

%Vor%

Nachdem diese Zeile ausgeführt wurde, habe ich einen anderen Code, der die Anzahl der Schiffe auf jedem der Planeten ändert, einschließlich der Planetenflotte. Leider spiegeln sich die Änderungen in der obigen Zeile nicht in dem QuerySet der Planeten, die ich früher erhalten habe, so dass, wenn ich alle Planeten am Ende des Zuges speichere, die Änderungen an den Schiffen von fleet.home überschrieben werden.

>

Gibt es einen besseren Weg, um mit dieser Situation umzugehen? Oder sind alle ORMs so?

    
Bobby Moretti 25.03.2009, 05:24
quelle

2 Antworten

20

Djangos ORM implementiert keine Identitätskarte (sie befindet sich im Ticket-Tracker , aber es ist nicht klar, ob und wann es implementiert wird, mindestens ein Django-Kern-Committer hat äußerte sich dagegen ). Wenn Sie also über zwei verschiedene Abfragepfade am gleichen Datenbankobjekt ankommen, arbeiten Sie mit verschiedenen Python-Objekten im Speicher.

Dies bedeutet, dass Ihr Design (Laden Sie alles in den Speicher auf einmal, ändern Sie viele Dinge, und speichern Sie dann alles zurück am Ende) ist nicht mit dem Django ORM funktionieren. Erstens, weil es häufig viel Speicherplatz in doppelte Kopien desselben Objekts lädt, und zweitens wegen "Überschreiben" von Problemen wie dem, in dem Sie gerade laufen.

Entweder müssen Sie Ihr Design überarbeiten, um diese Probleme zu vermeiden (entweder vorsichtig sein, mit jeweils nur einem QuerySet zu arbeiten, alles zu speichern, bevor Sie eine andere Abfrage erstellen, oder wenn Sie mehrere Abfragen laden, alle Relationen manuell nachschlagen, Verwenden Sie niemals die ForeignKeys, die die für sie geeigneten Attribute verwenden, oder verwenden Sie ein alternatives Python-ORM, das eine Identitätszuordnung implementiert. SQLAlchemy ist eine Option.

Beachten Sie, dass dies nicht bedeutet, dass Djangos ORM "schlecht" ist. Es ist optimiert für den Fall von Web-Anwendungen, wo solche Probleme selten sind (Ich habe seit Jahren Web-Entwicklung mit Django gemacht und hatte dieses Problem nie in einem realen Projekt). Wenn Ihr Anwendungsfall anders ist, möchten Sie möglicherweise ein anderes ORM auswählen.

    
Carl Meyer 25.03.2009, 15:16
quelle
1

Das ist vielleicht das, wonach Sie suchen:

Ссылка

    
Ólafur Nielsen 22.05.2009 14:34
quelle