2012-03-25 13 views
19

modele

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)) 

wyszukiwania

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

To nie działa .... Szukałem wszędzie i zapoznać się z dokumentacją. Ale po prostu nie widzę, jak mogę posortować moje zapytanie (Base) na ich nazwę relacji "właściciel".SQLAlchemy: Jak zamówić wyniki zapytania (order_by) na polu związku?

To zawsze skutkuje:

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

To musi być proste ... ale ja tego nie widzę. Zajrzałem również do Komparatorów, co wydawało się logiczne, ale nie widzę, gdzie generowana jest część zapytania dla ORDER BY lub co powinienem zwracać, ponieważ wszystko jest generowane dynamicznie. I robienie komparatora dla każdej z moich relacji gracza, aby zrobić prostą rzecz wydaje się zbyt skomplikowane.

Odpowiedz

30

SQLAlchemy chce, abyś myślał w kategoriach SQL. W przypadku zapytania "Baza":

SELECT * FROM base 

łatwe. W jaki sposób, w SQL, wybrałbyś wiersze z "bazy" i porządek według kolumny "nazwa" w zupełnie innej tabeli, czyli "odtwarzacz"? Za pomocą sprzężenia:

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

SQLAlchemy ma użyć identyczny proces myślowy - dołączeniu():

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

To ma sens. Ale to oznacza, że ​​mogę dołączyć tylko do jednej relacji gracza w danym momencie, prawda? Łączenie się z innymi (z jakiegokolwiek powodu ...) oznacza rozbijanie rzeczy. Więc jeśli chcesz zamówić przez updater, muszę to zrobić: session.query(Base).join(Base.updater).order_by(Player.name) lub 'okupant': session.query (Base) .join (Base.occupier) .order_by (Player.name) –

+2

można dołącz do pewnej tabeli dowolną liczbę razy, używając aliasów tej tabeli. Ponownie jest to koncepcja SQL, więc wiedząc, jak rozwiązać problem w SQL, będziesz wiedział, jak rozwiązać ten problem w SQLAlchemy. Aliasing został po raz pierwszy wprowadzony na http://docs.sqlalchemy.org/en/latest/orm/tutorial.html#using-aliases. – zzzeek

+0

Ta odpowiedź odfiltrowuje wszelkie obiekty 'base', w których' base.ownerid' ma wartość null. Czy wiesz, jak modyfikować podejście do porządku według wartości relacji, ale nie wykluczać obiektów, które nie mają wartości w związku? (być może zamawianie tych, którzy nie mają związku ostatni lub pierwszy) – melchoir55

Powiązane problemy