在SQLAlchemy中,是否有一种方法可以在单个查询中关闭声明式的多态联接加载?大多数情况下,它很好用,但我有以下问题:
除非使用outerjoin((B, B.id == A.id)),否则没办法避免在子查询中生成A和B中所有内容的全连接。如果B没有继承自A,则不会发生这种情况,因此我认为是多态声明性代码生成导致了这种情况。有没有方法可以关闭它?或者强制outerjoin执行我想要的操作?
我想要的是这样的东西:
但是我得到的却是这样的东西:
作为一个旁注,如果不可能实现这样的方式,那么后者是否比前者效率更低? SQL引擎是否会实际执行内部连接,还是会忽略它?
class A(Base) :
discriminator = Column('type', mysql.INTEGER(1), index=True, nullable=False)
__mapper_args__ = { 'polymorphic_on' : discriminator }
id = Column(Integer, primary_key=True)
p = Column(Integer)
class B(A) :
__mapper_args__ = { 'polymorphic_identity' : 0 }
id = Column(Integer, primary_key=True)
x = Column(Integer)
class C(A) :
__mapper_args__ = { 'polymorphic_identity' : 1 }
id = Column(Integer, primary_key=True)
y = Column(String)
我希望查询所有B.x大于10的A.id,如果这个A实际上是B,或者C.y等于'blah',如果这个A实际上是C,所有结果按照p排序。
为了迭代解决问题,我先从第一部分开始 - “查询所有B.x大于10的A.id,如果这个A实际上是B”。所以我想从一个外连接开始:
session.query(A.id).outerjoin((B, B.id == A.id)).filter(B.x > 10)
除非使用outerjoin((B, B.id == A.id)),否则没办法避免在子查询中生成A和B中所有内容的全连接。如果B没有继承自A,则不会发生这种情况,因此我认为是多态声明性代码生成导致了这种情况。有没有方法可以关闭它?或者强制outerjoin执行我想要的操作?
我想要的是这样的东西:
select a.id from A a left outer join B b on b.id == a.id where b.x > 10
但是我得到的却是这样的东西:
select a.id from A a left outer join (select B.id, B.x, A.id from B inner join A on B.id == A.id)
作为一个旁注,如果不可能实现这样的方式,那么后者是否比前者效率更低? SQL引擎是否会实际执行内部连接,还是会忽略它?