Seite 1 von 1

SQLAlchemy Foreign Key Beziehungen aut. herstellen

Verfasst: Freitag 11. April 2008, 18:40
von Jan-Peer
Hallo,

ich bin gerade dabei, mich ein bisschen näher mit SQLAlchemy zu beschäftigen. Dabei bin ich auf einen Punkt gestoßen, der mich ein wenig stört, und für den ich bislang keine Lösung gefunden habe.

Angenommen ich habe eine Datenbank mit mehreren Tabellen, und in der DB sind die Tabellen über Foreign Keys miteinander verknüpft. Jetzt erzeuge ich in einem Skript einige mappings zwischen Klassen und Tabellen und möchte natürlich auch die relations nutzen. Nur stört es mich, daß ich hierzu die ganzen Tabellenbeziehungen mittels relation-property nachbauen muß. Diese Informationen stecken doch in der DB - gibt es keine Möglichkeit, diese Beziehungen automatisch generieren zu lassen?

Re: SQLAlchemy Foreign Key Beziehungen aut. herstellen

Verfasst: Freitag 11. April 2008, 18:58
von Leonidas
Jan-Peer hat geschrieben:Angenommen ich habe eine Datenbank mit mehreren Tabellen, und in der DB sind die Tabellen über Foreign Keys miteinander verknüpft. Jetzt erzeuge ich in einem Skript einige mappings zwischen Klassen und Tabellen und möchte natürlich auch die relations nutzen. Nur stört es mich, daß ich hierzu die ganzen Tabellenbeziehungen mittels relation-property nachbauen muß. Diese Informationen stecken doch in der DB - gibt es keine Möglichkeit, diese Beziehungen automatisch generieren zu lassen?
Laut Dokumentation tut es das bereits.

Verfasst: Freitag 11. April 2008, 19:17
von Jan-Peer
Ja, so weit war mir das auch schon bekannt. Nur: Wenn ich jetzt ein Mapping von der Tabelle auf eine Klasse erstelle, dann über session.query Instanzen dieser Klasse erzeuge, kann ich nicht automatisch auf die Objekte einer verbundenen Tabelle zugreifen, einfach weil das entsprechende Attribut nicht zu existieren scheint.

Um bei den Beispielen aus dem Tutorial zu bleiben: Ich würde gerne auf einem User-Objekt einfach auf die dazugehörigen Email-Objekte zugreifen. Das geht, wenn ich im Mapping die property 'relation' setze. Nun denke ich, daß die Information, die ich 'relation' da übergebe ja eigentlich auch aus den in der DB definierten Foreign Keys ersichtlich sein müßte - demzufolge müßte es doch auch möglich sein, diese relations zu erzeugen, ohne sie explizit angeben zu müssen.

Verfasst: Samstag 12. April 2008, 10:59
von Y0Gi
Wieso steckt diese Verbindung in der Datenbank? Nur weil ein Feld auf "_id" endet, ergibt sich daraus ja nicht zwangsweise eine Relation zu einer bestimmten Tabelle.

Kann es sein, dass du in deinem Fall von der anderen Seite der Relation zugreifen willst? Möglicherweise musst du nur das `backref`-Keyword bei der Erstellung der Relation übergeben, damit es funktioniert.

Verfasst: Samstag 12. April 2008, 11:07
von Leonidas
Y0Gi hat geschrieben:Wieso steckt diese Verbindung in der Datenbank? Nur weil ein Feld auf "_id" endet, ergibt sich daraus ja nicht zwangsweise eine Relation zu einer bestimmten Tabelle.
In PostgreSQL gibt es Constraints über die man die Ralationen zwischen den Tabellen herausfinden kann. Aber nur sofern sie gesetzt werden, natürlich. Gibt es aber sicherlich nicht in jeder von SQLAlchemy unterstützten Datenbank.

Verfasst: Samstag 12. April 2008, 11:21
von Jan-Peer
Y0Gi hat geschrieben:Kann es sein, dass du in deinem Fall von der anderen Seite der Relation zugreifen willst? Möglicherweise musst du nur das `backref`-Keyword bei der Erstellung der Relation übergeben, damit es funktioniert.
Nein, das mit dem "backref" war mir durchaus bekannt. Mir ging es ja gerade darum, diesen ganzen "relation ... backref.." Schnippsel nicht einfügen zu müssen (schreibfaul bis ins Extrem).
Leonidas hat geschrieben: Gibt es aber sicherlich nicht in jeder von SQLAlchemy unterstützten Datenbank.
Gut, das Argument leuchtet ein. Damit will ich mich mal geschlagen geben. Soo viel Mehraufwand stellt das Einfügen von "relation" in ein Mapping nun auch wieder nicht dar. Und Hintergrundwissen über die Struktur der Datenbank muß ich eh haben ...

Vielen Dank und bis zum nächsten Mal

Verfasst: Samstag 12. April 2008, 12:47
von Y0Gi
Wenn dir SA in der Grundvariante zu explizit ist, kannst du mit dem deklarativen Mikrolayer einiges sparen (Spalten [oder die gesamte Tabelle] und Relationen werden in der Klasse definiert, die man sonst bei OR-Mapping "leer" erstellt, d.h. von `object` abgeleitet; der Mapper entfällt). Wenn dir das mit den expliziten ForeignKeys (also eine id-Spalte plus eine Relation) und das Anlegen der Relationen zuviel ist, könnte Elixir was für dich sein.

Ich persönlich bin den umgekehrten Weg von SQLObject über Elixir hin zu reinem SQLAlchemy gegangen. Mittlerweile benutze ich den Microlayer für einige Entities oder in einigen Projekten, aber letztlich gefällt mir das explizite doch sehr gut und Ben Bangert hat in seinem Elixir-Rant auch nicht ganz Unrecht ;)