2012-03-25 3 views
19

Modelle

from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import Column, ForeignKey 
from sqlalchemy import Integer 
from sqlalchemy import Unicode 
from sqlalchemy import TIMESTAMP 
from sqlalchemy.orm import relationship 

BaseModel = declarative_base() 

class Base(BaseModel): 
    __tablename__ = 'base' 
    id = Column(Integer, primary_key=True) 
    location = Column(Unicode(12), ForeignKey("locationterrain.location"), unique=True,) 
    name = Column(Unicode(45)) 
    ownerid = Column(Integer,ForeignKey("player.id")) 
    occupierid = Column(Integer, ForeignKey("player.id")) 
    submitid = Column(Integer,ForeignKey("player.id")) 
    updateid = Column(Integer,ForeignKey("player.id")) 
    owner = relationship("Player", 
     primaryjoin='Base.ownerid==Player.id', 
     join_depth=3, 
     lazy='joined') 
    occupier= relationship("Player", 
     primaryjoin='Base.occupierid==Player.id', 
     join_depth=3, 
     lazy='joined') 
    submitter = relationship("Player", 
     primaryjoin='Base.submitid== Player.id', 
     join_depth=3, 
     lazy='joined') 
    updater= relationship("Player", 
     primaryjoin='Base.updateid== Player.id', 
     join_depth=3, 
     lazy='joined') 


class Player(BaseModel): 
    __tablename__ = 'player' 
    id = Column(Integer, ForeignKey("guildmember.playerid"), primary_key=True) 
    name = Column(Unicode(45)) 

bases = dbsession.query(Base) 
bases = bases.order_by(Base.owner.name) 

arbeiten Dies gilt nicht Searching .... Ich habe überall gesucht und die Dokumentation lesen. Aber ich sehe einfach nicht, wie ich meine (Base) Abfrage nach dem Namen ihrer 'Besitzer'-Beziehung sortieren kann.SQLAlchemy: Wie Abfrageergebnisse (order_by) in einem Beziehungsfeld bestellen?

Es führt immer zu:

AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object has an attribute 'name' 

Diese einfach sein muss ... aber ich sehe es nicht. Ich habe auch nach Comparators gesucht, was logisch erschien, aber ich sehe nicht, wo der Abfrageteil für ORDER BY generiert wird oder was ich zurückgeben sollte, da alles dynamisch generiert wird. Und einen Vergleicher für jede meiner "Spieler" -Beziehungen zu erstellen, um eine einfache Sache zu tun, scheint zu kompliziert zu sein.

Antwort

30

SQLAlchemy möchte, dass Sie in Bezug auf SQL denken. Wenn Sie eine Abfrage für "Base" ausführen, lautet die folgende Nummer:

SELECT * FROM base 

einfach. Wie würden Sie also in SQL die Zeilen von "base" auswählen und nach der "name" -Spalte in einer völlig anderen Tabelle sortieren, also "player"? Sie verwenden einen Join:

SELECT base.* FROM base JOIN player ON base.ownerid=player.id ORDER BY player.name 

SQLAlchemy hat man die gleiche Denkprozess verwenden - Sie kommen():

session.query(Base).join(Base.owner).order_by(Player.name) 
+0

, die Sinn macht. Aber das bedeutet, dass ich nur einer der Spielerbeziehungen gleichzeitig beitreten kann, oder? Mehr zu tun (aus welchem ​​Grund auch immer ...) bedeutet, Dinge zu brechen. Also, wenn ich von Updater bestellen will, muss ich dies tun: session.query(Base).join(Base.updater).order_by(Player.name) oder 'Besatzer': session.query (Basis) .join (Base.occupier) .order_by (Player.name) –

+2

möglich Join zu einer bestimmten Tabelle beliebig oft mit Aliase dieser Tabelle. Auch dies ist ein SQL-Konzept. Wenn Sie also wissen, wie Sie das Problem in SQL lösen, wissen Sie, wie Sie es in SQLAlchemy lösen können. Aliasing wird zuerst unter http://docs.sqlalchemy.org/en/latest/orm/tutorial.html#using-aliases eingeführt. – zzzeek

+0

Diese Antwort würde alle Basisobjekte ausfiltern, bei denen "base.ownerid" null ist. Wissen Sie, wie Sie den Anordnungsmodus nach Beziehungswerten ändern, aber nicht Objekte ausschließen, die in der Beziehung keine Werte enthalten? (vielleicht bestellt man diejenigen ohne die letzte oder erste Beziehung) – melchoir55