gpt4 book ai didi

python - sqlalchemy:关闭声明式多态连接?

转载 作者:太空宇宙 更新时间:2023-11-03 11:35:50 24 4
gpt4 key购买 nike

在 sqlalchemy 中有没有办法在单个查询中关闭声明式的多态连接加载?大多数时候它很好,但我有:

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)

我想做一个查询,如果 A 实际上是 B,或者 C.y == 'blah',如果 A 实际上是 C,那么我得到所有 A.ids,其中 B.x > 10,全部有序由 p.

为了迭代地进行,我从第一部分开始——“如果 A 实际上是 B,则获取所有 B.x > 10 的 A.id”。所以我想我会从外部连接开始:

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 引擎实际上会执行该内部联接,还是会忽略它?

最佳答案

您可以尝试分别为每个子类构建查询,然后将它们合并在一起。查询 B.id 时,SQLAlchemy 隐式加入父类(super class)并返回 A.id ,因此采用 B.idC.id 只返回一个列。

>>> b_query = session.query(B.id).filter(B.x > 10)
>>> c_query = session.query(C.id).filter(C.y == 'foo')
>>> print b_query.union(c_query)
SELECT anon_1."A_id" AS "anon_1_A_id"
FROM (SELECT "A".id AS "A_id"
FROM "A" JOIN "B" ON "A".id = "B".id
WHERE "B".x > ? UNION SELECT "A".id AS "A_id"
FROM "A" JOIN "C" ON "A".id = "C".id
WHERE "C".y = ?) AS anon_1

您仍然会得到一个子选择,但只有一个“层”的连接 - 外部选择只是重命名该列。

关于python - sqlalchemy:关闭声明式多态连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3630310/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com