简体   繁体   English

SQLalchemy:使用 Union 细化和链接子查询

[英]SQLalchemy: refine and chaining subquery with Union

I would like to construct a query with sqlalchemy, while using the ORM extension.我想用 sqlalchemy 构造一个查询,同时使用 ORM 扩展。 Consider this:考虑一下:

class Foo(Base):
    __table__ = 'foo_table'
    id = Column(Integer)
    name = Column(String)
    prop = Column(Integer)

now I would like to write a general function, which can return me all Foo's where the name matches some string or where the prop is some number:现在我想编写一个通用函数,它可以返回名称与某个字符串匹配的所有 Foo 或 prop 是某个数字的所有 Foo:

from sqlalchemy.orm import Query
def match_name(_name):
    return Query(Foo).filter_by(name = _name)

def match_prop(_prop):
    return Query(Foo).filter_by(prop = _prop)

Each function should be able to return me an Query, which I can use retrieve ORM objects.每个函数都应该能够返回一个查询,我可以使用它来检索 ORM 对象。 Now considering I am only interested in id and name of these objects, but without altering the functions, I can operate like this:现在考虑到我只对这些对象的 id 和 name 感兴趣,但不改变函数,我可以这样操作:

myname = 'foo'
sqry1 = match_name(myname).subquery()
all_name_eq_foo = session.query(sqry1.c.id, sqry1.c.name).all()

myprop = 42
sqry2 = match_prop(myprop).subquery()
all_name_eq_foo = session.query(sqry2.c.id, sqry2.c.name).all()

So, now, how to achieve this in one go, while using the superset of results in each subquery, aka where name matches OR prop matches without, without chaining the filter conditions (the subqueries in this example are just simplified, but might are more complicated for usecase).所以,现在,如何在不链接过滤条件的情况下,在每个子查询中使用结果的超集,也就是名称匹配OR属性匹配,而不链接过滤条件(本示例中的子查询只是简化,但可能更多用例复杂)。 For me this means using Union , thus something like this:对我来说,这意味着使用Union ,因此是这样的:

def match_name_prop(_name, _prop):
    return Query.union([match_name(_name).subquery(), match_prop(_prop).subquery()])

with the possibility to later limit the resulting columns:以后可以限制结果列:

sqry3 = match_name_prop(myname, myprop).subquery()
all_name_eq_foo = session.query(sqry3.c.id, sqry3.c.name).all()

But I cannot get this working.但我不能让它工作。 Can anybody please help?!有人可以帮忙吗?!

After hours of trying, I think I found an adequate solution:经过几个小时的尝试,我想我找到了一个合适的解决方案:

def match_name_prop(_name, _prop):
    return match_name(_name).union(match_prop(_prop))

which by itself will return ORM-entities like so:它本身将返回 ORM 实体,如下所示:

matches = match_name_prop(myname, myprop)
matches.with_session(session).all()
#>>> [<Foo object at 0xFFFFFF>]

and then subselecting of desired columns within that entity like so:然后在该实体中子选择所需的列,如下所示:

session.query(Foo.id, Foo.name).select_entity_from(matches.subquery()).all()
#>>> [(42,'foo',)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM