2011-12-19 47 views
49

我對SQLAlchemy和一個問題沒有太多的經驗,我無法解決這個問題,但是正在嘗試大量代碼。 這是我的班(減少到最顯著代碼):SqlAlchemy - 通過關係屬性進行篩選

class Patient(Base): 
    __tablename__ = 'patients' 
    id = Column(Integer, primary_key=True, nullable=False) 
    mother_id = Column(Integer, ForeignKey('patients.id'), index=True) 
    mother = relationship('Patient', primaryjoin='Patient.id==Patient.mother_id', remote_side='Patient.id', uselist=False) 
    phenoscore = Column(Float) 

,我想查詢所有的病人,他的母親的phenoscore是(例如)== 10

至於說,我試着很多代碼,但我沒有明白。該邏輯的解決方案,在我眼裏,是

patients = Patient.query.filter(Patient.mother.phenoscore == 10) 

,因爲,你可以爲每個元素訪問.mother.phenoscore輸出的時候,但是,此代碼不會做。 是否存在根據關係的屬性進行過濾(直接)的可能性(無需編寫SQL語句或額外的連接語句),我需要多次這種過濾器。

即使沒有簡單的解決辦法,我很高興所有的答案

非常感謝 克里斯托

回答

88

使用方法的關係has()(更易讀):

patients = Patient.query.filter(Patient.mother.has(phenoscore=10)) 

或加入(通常更快):

patients = Patient.query.join(Patient.mother, aliased=True)\ 
        .filter_by(phenoscore=10) 
+5

患者= Patient.query.filter(Patient.mother.has(Patient.phenoscore == 1 0)) – user1105851 2011-12-19 15:42:50

+0

@ user1105851'has()'支持條件表達式作爲未命名的參數和'filter_by'樣式的關鍵字參數。後者似乎對我更可讀。 – 2011-12-19 16:03:04

+0

@DenisOtkidach正確,但它會是'phenoscore = 10'。 'filter_by'只需要相等關鍵字(因爲它只是對它們進行** kwargs) – aruisdante 2014-04-01 17:47:46

2

好消息告訴你:我最近做了包,讓你過濾/用「神奇」的字符串as in Django排序,所以你現在就可以編寫類似

Patient.where(mother___phenoscore=10) 

這是短了很多,尤其是對於複雜的過濾器,也就是說,

Comment.where(post___public=True, post___user___name__like='Bi%') 

何PE你會喜歡這個包

https://github.com/absent1706/sqlalchemy-mixins#django-like-queries

1

我與會話中使用它,但在這裏你可以訪問關係領域的另一種方法是直接

db_session.query(Patient).join(Patient.mother) \ 
    .filter(Patient.mother.property.mapper.class_.phenoscore==10) 

我沒有測試過,但我想這也將工作

Patient.query.join(Patient.mother) \ 
    .filter(Patient.mother.property.mapper.class_.phenoscore==10)