简体   繁体   中英

SQLAlchemy relationship with self-referential secondary

I have the following scenario:

class A(Base):
    a_string = Column(String)

class B(Base):
    id = Column(Integer, primary_key=True)

class C(Base):
    b_id = Column(Integer, ForeignKey(B.id))
    value = Column(String)

I need to do the following query:

SELECT c2.*
  FROM a
  JOIN c c1 on c1.value = a.a_string
  JOIN c c2 on c2.b_id = c1.b_id

The problem is that I need to do the query above in a relationship inside the model A. Something like:

class A(Base):
    a_string = Column(String)
    c_list = relationship('C', secondary=...)

You'll need an alias for C in order to self join:

In [3]: c_to_c = aliased(C.__table__)

With that you can then define the primary and secondary joins to suit your needs. This relationship should probably be view only:

In [4]: A.c_list = relationship(
   ...:     C, secondary=c_to_c,
   ...:     primaryjoin=A.a_string == c_to_c.c.value,
   ...:     secondaryjoin=C.b_id == c_to_c.c.b_id,
   ...:     viewonly=True
   ...: )

You can then verify that you can for example use joined eager loading:

In [5]: print(session.query(A).options(joinedload(A.c_list)))
SELECT a.id AS a_id, a.a_string AS a_a_string, c_1.id AS c_1_id, c_1.b_id AS c_1_b_id, c_1.value AS c_1_value 
FROM a LEFT OUTER JOIN (c AS c_2 JOIN c AS c_1 ON c_1.b_id = c_2.b_id) ON a.a_string = c_2.value

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM