2016-11-15 12 views
7

Tôi có các lớp sau:tương ứng một mối quan hệ SQLAlchemy với một vụng về tham gia

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

Nói cách, tôi đang cố gắng để tạo ra một mối quan hệ maximum_a với a_id lớn nhất của tất cả của A trỏ đến bởi một B cho Tôi đặc biệt muốn điều này là một mối quan hệ để tôi có thể tìm nạp trước nó với joinedload để tránh trường hợp chúng tôi hiện có các truy vấn O (N).

Khi tôi cố gắng tải trước các mối quan hệ maximum_a (ví dụ như thông qua session.query(B).options(joinedload('maximum_a')).all()), tôi nhận được lỗi sau:

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. 

Tôi đã cố gắng để đọc các tài liệu SQLA trên tương quan, nhưng tất cả họ đang viết bằng các điều khoản của raw select thay vì các cuộc gọi ORM và các mô tả không rõ ràng, vì vậy tôi không chắc chắn nơi để thêm cuộc gọi correlate - hoặc nếu có cách tốt hơn để thực hiện việc này.

Mọi đề xuất? Cảm ơn!

+0

Có lẽ có một cái nhìn tại [thừa kế và đa hình bốc] (http://docs.sqlalchemy.org/en/latest/orm/inheritance.html# join-table-inheritance) – sytech

+0

Bạn có thể mở rộng về mức độ liên quan của nó không? Vấn đề này dường như không liên quan gì đến thừa kế hay đa hình. –

+1

Xin lỗi, Ben. Tôi có thể đã đọc sai câu hỏi này. Tôi đã gợi ý thừa kế như một phương tiện để có được kết quả mong muốn, nhưng sau khi đọc lại câu hỏi, tôi không nghĩ nó phù hợp với trường hợp của bạn. – sytech

Trả lời

6

Sau khi thử nhiều, đây là những gì làm việc:

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) 
Các vấn đề liên quan