2012-08-09 7 views
5

Angenommen, ich habe folgende SQLAlchemy Klassen definiert:Wie kann ich den Typ einer dynamischen SQLAlchemy-Beziehung bestimmen (z. B. mehrere zu eins)?

Base = declarative_base() 

class Person(Base): 
    __tablename__ = 'person' 
    id = Column(Integer, primary_key=True) 
    computers = relationship('Computer', backref=backref('owner', lazy='dynamic')) 

class Computer(Base): 
    __tablename__ = 'computer' 
    id = Column(Integer, primary_key=True) 
    ownerid = Column(Integer, ForeignKey('person.id')) 

weiter Angenommen, dass ich die faule Abfrageobjekt auf diese Weise aufgerufen haben:

relation = getattr(Computer, 'owner') 

Wie kann ich feststellen, ob relation auf eine einzelne Instanz bezieht sich der Person (also in einer Viele-zu-Eins-Beziehung, wie in diesem Beispiel), oder wenn sich relation auf eine Sammlung von Instanzen bezieht (wie in einer Eins-zu-viele-Beziehung)? Mit anderen Worten: Wie kann ich den Beziehungstyp eines dynamischen SQLAlchemy-Beziehungsobjekts ermitteln?

+0

Ich bin nicht sicher, ob ich die Frage richtig verstehe, aber in Ihrem Beispiel, warum überprüfen Sie nicht einfach, ob es eine Sammlung (z. B. eine Liste) oder ein einzelnes Element ist? Dies ist völlig unabhängig von SQLAlchemy und würde die ORM-Funktion von SQLAlchemy nutzen und vollständig von der Datenbank abstrahieren. – javex

+0

Sie haben meistens Recht: Ich denke, die richtige Lösung ist es, zu überprüfen, ob 'isinstance (relation, list)' --- falls wahr, dann können wir es einfach wie eine Liste verwenden, aber wenn falsch, muss man 'relation.one') ', um die Beziehung zu einer konkreten Instanz abzubilden. Wenn du unten eine Antwort hinzufügst, kann ich dich belohnen (bitte nimm die Einschränkung, die ich hier angegeben habe, wenn du kannst). – argentpepper

Antwort

2

Wenn wir model = Computer und relation = 'owner' wie in der Frage annehmen, dann ist das folgende Attribut True, wenn und nur wenn die Beziehung eine Liste der Instanzen ist als auf eine einzelne Instanz gegen:

model._sa_class_manager[relation].property.uselist 

können Sie dann verwenden, dies zu testen, ob die one() Methode auf dem Ergebnis der getattr(model, relation) zu nennen:

if model._sa_class_manager[relation].property.uselist: 
    related_instances = getattr(model, relation) 
else: 
    related_instance = getattr(model, relation).one() 

ich bin nicht sicher, aber, dass dies die beste Lösung ist.

Verwandte Themen