2010-05-27 6 views
23

Ich bin kein Datenbankexperte - ich kenne nur die Grundlagen, wirklich. Ich habe SQLAlchemy für ein kleines Projekt ausgewählt, und ich benutze die deklarative Basiskonfiguration anstatt die "normale" Art und Weise. Dieser Weg scheint viel einfacher.Wie funktionieren einfache SQLAlchemy-Beziehungen?

Beim Einrichten meines Datenbankschemas habe ich jedoch festgestellt, dass ich einige Datenbankbeziehungskonzepte nicht verstehe.

Wenn ich zuvor eine Viele-zu-Eins-Beziehung hatte, zum Beispiel Artikel von Autoren (wo jeder Artikel nur von einem einzigen Autor geschrieben werden könnte), würde ich ein author_id Feld in meine articles Spalte setzen. Aber SQLAlchemy hat dieses ForeignKey-Objekt und eine Beziehungsfunktion mit einem Backref-Kwarg, und ich habe keine Ahnung, was das bedeutet.

Ich habe Angst, herauszufinden, wie eine Viele-zu-Viele-Beziehung mit einer Zwischentabelle aussieht (wenn ich zusätzliche Daten über jede Beziehung benötige).

Kann jemand das für mich entmystifizieren? Im Moment richte ich ein, um openID auth für meine Anwendung zuzulassen. Also habe ich diese bekam:

from __init__ import Base 
from sqlalchemy.schema import Column 
from sqlalchemy.types import Integer, String 

class Users(Base): 
    __tablename__ = 'users' 
    id = Column(Integer, primary_key=True) 
    username = Column(String, unique=True) 
    email = Column(String) 
    password = Column(String) 
    salt = Column(String) 


class OpenID(Base): 
    __tablename__ = 'openid' 
    url = Column(String, primary_key=True) 
    user_id = #? 

Ich denke, die ? sollte durch Column(Integer, ForeignKey('users.id')) ersetzt werden, aber ich bin mir nicht sicher - und brauche ich openids = relationship("OpenID", backref="users") in der Benutzerklasse setzen? Warum? Was tut es? Was ist ein Backref?

Antwort

35

Ja, Sie benötigen user_id = Column(Integer, ForeignKey('users.id')) oder user_id = Column(Integer, ForeignKey('users.id'), nullable=False), wenn es obligatorisch ist. Dies wird direkt in FOREIGN KEY im zugrundeliegenden Datenbankschema übersetzt, keine Magie.

Die einfache Art, eine Beziehung zu deklarieren, ist user = relationship(Users) in OpenID Klasse. Sie können auch users = relationship('OpenID') in Users Klasse verwenden. backref Parameter ermöglicht es Ihnen, beide Beziehungen mit einer einzelnen Deklaration zu deklarieren: es bedeutet, rückwärts Beziehung in verwandten Klassen automatisch zu installieren. Ich persönlich bevorzuge die Verwendung von backref -s nur für selbstbezogene Beziehungen. Der Grund ist, dass ich selbst dokumentierten Code mag: Wenn Sie durch die Definition schauen, sehen Sie alle definierten Eigenschaften, während Sie mit backref andere Klassen durchsehen müssen (wahrscheinlich in anderen Modulen definiert).

+0

Große Antwort, danke. Ich bin irgendwie überrascht, dass es so lange gedauert hat und niemand anders geantwortet hat ... Scheint so, als ob viele Leute davon erfahren würden. Oh gut :) –

+2

Dies ist eine gute Antwort, sehr klar. Ich bevorzuge auch selbst dokumentierten Code. Zu diesem Zweck stellt SQLAlchemy seit 0.5.1 eine Alternative zu "backref" bereit, die ['back_populate'] ist (http://docs.sqlalchemy.org/en/latest/orm/relationship_api.html#sqlalchemy.orm). beziehung.params.back_bevölkert). Die Dokumente präsentieren weitere Erläuterungen und ein Beispiel: http://docs.sqlalchemy.org/en/latest/orm/backref.html#relationships-backref – iled