2009-04-17 9 views
2

Aus Leistungsgründen kann ich die ORM-Abfragemethoden von Django nicht verwenden, und ich muss Raw-SQL für einige komplexe Fragen verwenden. Ich möchte eine Möglichkeit finden, die Ergebnisse einer SQL-Abfrage mehreren Modellen zuzuordnen.Zuordnung von Raw-SQL zu mehreren verwandten Django-Modellen

Ich weiß, dass ich die folgende Anweisung verwenden kann, um die Abfrageergebnisse einem Modell zuzuordnen, aber ich kann nicht herausfinden, wie man es verwendet, um verwandte Modelle zuzuordnen (wie ich mit der select_related-Anweisung in Django).

model_instance = MyModel(**dict(zip(field_names, row_data))) 

Gibt es eine relativ einfache Möglichkeit, Felder verwandter Tabellen zuzuordnen, die sich ebenfalls in der Abfrageergebnismenge befinden?

Antwort

1

Erstens, können Sie beweisen, dass das ORM Ihre Leistung stoppt? Manchmal sind Leistungsprobleme einfach ein schlechtes Datenbankdesign oder fehlerhafte Indizes. In der Regel kommt dies daher, dass versucht wird, Djangos ORM an ein Legacy-Datenbank-Design anzupassen. Gespeicherte Prozeduren und Trigger können sich negativ auf die Leistung auswirken, insbesondere wenn Sie mit Django arbeiten, bei dem erwartet wird, dass der Triggercode im Python-Modellcode enthalten ist.

Manchmal schlechte Leistung ist ein Anwendungsproblem. Dies beinhaltet unnötige Order-by-Operationen in der Datenbank.

Das häufigste Leistungsproblem ist eine Anwendung, die Daten "überlädt". Verwenden Sie die Methode .all() beiläufig und erstellen Sie große Sammlungen im Speicher. Dies wird die Leistung beeinträchtigen. Die Django-Abfragesätze müssen so wenig wie möglich berührt werden, damit der Iterator für die Abfragegruppe der Vorlage zur Anzeige übergeben wird.

Sobald Sie gewählt haben, das ORM zu umgehen, müssen Sie das Objekt-Relationale Impedanz-Mismatch-Problem bekämpfen. Nochmal. Insbesondere hat relationale "Navigation" kein Konzept von "verwandt": Es muss ein First-Class-Abruf eines relationalen Satzes sein, der Fremdschlüssel verwendet. Ein komplexes In-Memory-Objektmodell über SQL zu erstellen, ist einfach schwierig. Zirkuläre Verweise machen dies sehr schwierig; Das Auflösen von FKs in Sammlungen ist schwierig.

Wenn Sie Raw SQL verwenden, haben Sie zwei Möglichkeiten.

  1. Essew "select related" - es existiert nicht - und es ist schmerzhaft zu implementieren.

  2. Erfinden Sie Ihre eigenen ORM-ähnlichen "select related" -Features. Ein allgemeiner Ansatz besteht darin, statusbehaftete Getter hinzuzufügen, die (a) einen privaten Cache prüfen, um zu sehen, ob sie das zugehörige Objekt abgerufen haben und ob das Objekt nicht existiert, (b) das zugehörige Objekt aus der Datenbank holt und den Cache aktualisiert.

Im Prozess Ihre eigenen Stateful Getter zu erfinden, werden Sie neu zu erfinden Djangos werden, und Sie werden wahrscheinlich feststellen, dass es nicht die ORM-Schicht, sondern eine Datenbank-Design oder eine Anwendung Design-Problem ist.

+0

Das Leistungsproblem liegt an der Art, wie ich einige Einschränkungen im ORM selbst umgehen musste. Das Datenbankdesign ist gut (keine Legacy-Datenbank). Vielleicht sollte ich fragen, ob es eine einfachere Möglichkeit gibt, die Abfrage mit Django zu schreiben. In SQL ist die Abfrage sehr einfach. Aber das wäre ein Thema für sich. ;-) – Michael

+1

Das ist mein Punkt - lass die Django ORM Abfrage im Django ORM funktionieren und alles wird besser. Was auch immer die "Einschränkungen" sind, es kann ein einfaches Missverständnis oder ein Problem mit dem Anwendungsdesign sein, das behoben werden kann. –

+1

Die Antwort löst die Frage nicht, stattdessen schlägt das Problem wahrscheinlich anderswo vor. Abgestimmt. Selbst ein gut entworfenes DB-Schema kann Leistungsprobleme bei der Skalierung auf einer bestimmten DB-Plattform aufgrund der Unzulänglichkeiten der Plattform haben. Diese Unzulänglichkeiten können durch Optimierungen in unformatierten Abfragen vollständig überwunden werden, was bedeutet, dass ein Problem mit der Anwendung oder dem Schemadesign unbegründet ist. Manchmal ist das Problem/ist/die Datenbank und das ist die Frage, die gestellt wurde. – stealthwang

Verwandte Themen