2016-11-15 55 views
7

我有以下類別:進行相關了一個困難的一SQLAlchemy的關係加入

class A: 
    a_id = Column(Integer, primary_key=True) 
    a_remote = Column(UnicodeText) 

class B: 
    b_id = Column(Integer, primary_key=True) 
    foreign_to_a = Column(UnicodeText) 
    maximum_a = relationship(A, primaryjoin=lambda: 
     and_(remote(a_remote) == foreign(foreign_to_a), 
      A.a_id = select([func.max(A.a_id)]).where(A.a_remote == B.foreign_to_a)) 
    ) 

在的話,我想創建的所有A的最大a_id的關係maximum_a指向給定的乙。我特別希望這是一種關係,以便我可以使用joinedload預取它,以避免出現O(N)查詢的情況。

當我嘗試預裝maximum_a關係(例如通過session.query(B).options(joinedload('maximum_a')).all()),我收到以下錯誤:

sqlalchemy.exc.InvalidRequestError: Select statement 'SELECT max(a_1.a_id) AS max_1 
FROM a AS a_1, b 
WHERE a_1.a_remote = b.foreign_to_a' returned no FROM clauses due to auto-correlation; specify correlate(<tables>) to control correlation manually. 

我試圖讀出相關的SQLA文檔,但他們都寫在原始select的條款而不是ORM調用,並且說明不是很清楚,所以我不確定在哪裏添加correlate調用 - 或者是否有更好的方法來執行此操作。

有什麼建議嗎?謝謝!

+0

也許看一看[傳承與多態裝填](http://docs.sqlalchemy.org/en/latest/orm/inheritance.html#連接表繼承) – sytech

+0

你可以擴展它的相關性嗎?這個問題似乎與繼承或多態性沒有任何關係。 –

+1

對不起,本。我可能誤解了這個問題。我建議將繼承作爲獲得理想結果的手段,但在重讀這個問題後,我認爲它不適合你的情況。 – sytech

回答

6

大量嘗試後,這裏是什麼工作:

class A: 
    a_id = Column(Integer, primary_key=True) 
    a_remote = Column(UnicodeText) 

latest_a = select([ 
    func.max(A.a_id).label('a_id'), A.a_remote 
]).group_by(A.a_remote).alias('latest_a') 

class B: 
    b_id = Column(Integer, primary_key=True) 
    foreign_to_a = Column(UnicodeText) 
    maximum_a = relationship(A, 
     secondary=latest_a, 
     primaryjoin=latest_a.c.a_remote == foreign_to_a, 
     secondaryjoin=latest_a.c.a_id == A.a_id, 
     uselist=False, viewonly=True)