Is there a way in sqlalchemy to turn off declarative's polymorphic join loading, in a single query? Most of the time it's nice, but I have:
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)
I want to make a query such that I get all A.ids for which B.x > 10, if that A is actually a B, or where C.y == 'blah', if that A is actually a C, all ordered by p.
To do it iteratively, I'm starting just with the first part - "get all A.id for which B.x > 10 if that A is actually a B". So I thought I would start with an outer join:
session.query(A.id).outerjoin((B, B.id == A.id)).filter(B.x > 10)
... except there seems to be no way to avoid having that outerjoin((B, B.id == A.id)) clause generate a full join of everything in A to everything in B within a subselect. If B doesn't inherit from A, then that doesn't happen, so I'm thinking it's the polymorphic declarative code generation that does that. Is there a way to turn that off? Or to force the outerjoin to do what I want?
What I want is something like this:
select a.id from A a left outer join B b on b.id == a.id where b.x > 10
but instead I get something like:
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)
... as an aside, if it's not possible, then is the latter less efficient than the former? Will the sql engine actually perform that inner join, or will it elide it?