SqlAlchemy:检查一个对象是否存在任何关系(or_(object.relationship1.contains(otherObject), object.relationship2.contains(otherObject))
假设我有一个这样的类:(
class Foo(declarativeBase):
bars1 = relationship(Bar.Bar, secondary=foos_to_bars1, collection_class=set())
bars2 = relationship(Bar.Bar, secondary=foos_to_bars2, collection_class=list())
每个关系都给我提供具有特定条件的“Bar”)。在某个时刻,我想获取在任何关系中具有“bar”(Bar.Bar 的实例)的“Foo”的实例。
如果我尝试这样做:
def inAnyBar(bar)
query(Foo).filter(or_(Foo.bars1.contains(bar), Foo.bars2.contains(bar)).all()
我会得到一个空结果。
它看起来(对我来说)就像我正在做类似的事情:
query(Foo).join(Foo.bars1).filter(Foo.bars1.contains(bar)).\
join(Foo.bars2).filter(Foo.bars1.contains(bar))
由于 Foo.bars1 不包含 bar,所以第二个过滤器给出空结果。
我已经能够找到子查询的解决方法(子查询中的每个 join+filter,然后 or_ 所有子查询),但我想知道是否有更好的方法来做到这一点......
我发现了这个: http://techspot.zzzeek.org/2008/09/09/selecting- booleans/
这就是我想做的,但它是针对 SqlAlchemy 0.5 的,我(几乎)确定有一种“更干净”的方法可以用 SqlAlchemy 0.6.6 来完成它,
谢谢!
Let's say I have a class like this:
class Foo(declarativeBase):
bars1 = relationship(Bar.Bar, secondary=foos_to_bars1, collection_class=set())
bars2 = relationship(Bar.Bar, secondary=foos_to_bars2, collection_class=list())
(Each of the relationships gives me "Bar"s with a certain conditions). At a certain point, I want to get instances of "Foo"s that have a "bar" (instance of Bar.Bar) in any of the relationships.
If I try to do:
def inAnyBar(bar)
query(Foo).filter(or_(Foo.bars1.contains(bar), Foo.bars2.contains(bar)).all()
I get an empty result.
It looks (to me) like I'm doing something like:
query(Foo).join(Foo.bars1).filter(Foo.bars1.contains(bar)).\
join(Foo.bars2).filter(Foo.bars1.contains(bar))
Since Foo.bars1 doesn't contain bar, the second filter gives empty results.
I've been able to find a workaround with subqueries (each join+filter in a subquery, then or_ all the subqueries) but I'd like to know if there's a better way to do it...
I found this:
http://techspot.zzzeek.org/2008/09/09/selecting-booleans/
That does what I want to do, but it's for SqlAlchemy 0.5 and I'm (almost) certain that there's a "cleaner" way to do it with SqlAlchemy 0.6.6
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你是对的,
session.query(Foo).filter(Foo.bars1.contains(bar)|Foo.bars2.contains(bar))
产生以下 SQL:当以下之一时返回不正确的结果
辅助
表为空。看起来像是 SQLAlchemy 中的一个错误。但是,用any()
替换contains()
解决了问题(它使用 EXISTS 子查询):您也可以显式指定 OUTER JOIN:
You are right,
session.query(Foo).filter(Foo.bars1.contains(bar)|Foo.bars2.contains(bar))
produces the following SQL:which returns incorrect result when one of the
secondary
tables is empty. Seems like a bug in SQLAlchemy. However replacingcontains()
withany()
fixed the problem (it uses EXISTS subqueries):Also you can specify OUTER JOIN explicitly: