SQLAlchemy与复合联接的关系

时间:2018-11-14 17:26:41

标签: python sqlalchemy

我试图找到正确的方法来指定在两个相关表的条件下联接的SQL炼金术表之间的关系。

我有一个等同于以下内容的SQL语句:

select a.id
     , b.id
     , b.b_val
     , c.id
     , c.c_dt
     , c.c_val
from a
join b
  on a.id = b.id
join c
  on b.id = c.id
  and a.date <-= c.date
  and a.date < current_date;

我目前从SQLAlchemy中得到的是:

print(q)

SELECT schema.a.id AS schema_a_id
     , schema.b.id AS schema_b_id
     , schema.b.b_val AS schema_b_b_val
     , schema.c.id AS schema_c_id
     , schema.c.c_dt AS schema_c_c_dt
     , schema.c.c_val AS schema_c_c_val 
FROM schema.a 
JOIN schema.b 
  ON schema.a.id = schema.b.id 
JOIN schema.c 
  ON schema.a.secondary_id = schema.c.id
  -- I'm missing the rest of the join clause here

我被c表的联接条件所困扰。在其中,我想对带有两个条件的date列使用约束。我尝试在我的人际关系中使用primaryjoin字段来执行此操作,但到目前为止还算不上成功。

这是我的最小可重复示例:

Base = declarative_base()

class A(Base):
    __tablename__ = 'a'
    __table_args__ = {'schema':'schema'}
    id = Column(Integer(), primary_key=True)
    secondary_id = Column(Integer())
    a_dt = Column(Date())
    b_rel = relationship('b', uselist=False, back_populates="a")
    c_rel = relationship('c', primaryjoin="and_(a.a_dt >= c.c_dt, a.a_dt < func.current_date())")

class B(Base):
    __tablename__ = 'b'
    __table_args__ = {'schema':'schema'}
    id = Column(Integer, ForeignKey(A.id), primary_key=True)
    b_val = Column(Integer())

class C(Base):
    __tablename__ = 'c'
    __table_args__ = {'schema':'schema'}
    id = Column(Integer(), ForeignKey(A.secondary_id), primary_key=True)
    c_dt = Column(Date())
    c_val = Column(Integer())

engine = create_engine('teradatasql://'+user+':'+pswd+'@'+host)

Session = sessionmaker()
Session.configure(bind=engine)
sess = Session()

q = sess.query(A.id, B.id, B.b_val, C.id, C.c_dt, C.c_val).join(B).join(C)

# result is shown above

我可能要添加些什么来使这种关系正常运行?

0 个答案:

没有答案