sqlalchemy过滤多列


81

如何合并两列并应用过滤器?例如,我要同时搜索“名字”和“姓氏”列。如果仅搜索一列,这就是我的操作方式:

query = meta.Session.query(User).filter(User.firstname.like(searchVar))

4
我以为这个问题与我遇到的问题匹配,但是答案不适用于我的特定情况。如果firstname是“ joe smith”,lastname是“ smith”,则我正在寻找一个过滤器语句,该语句将在提供的searchVar是“ joe smith”时匹配。即,在进行测试之前,需要将字段连接起来(添加空格)。似乎是一个非常现实的场景。
Groovee60,2015年

1
@ Groovee60这正是我在寻找的东西。如果您能够共享自己的解决方案(如果找到了一个解决方案),我将不胜感激。
Lilylakshi '17

Answers:


80

有很多方法可以做到这一点:

使用filter()运算子)

query = meta.Session.query(User).filter(
    User.firstname.like(search_var1),
    User.lastname.like(search_var2)
    )

使用filter_by()运算子)

query = meta.Session.query(User).filter_by(
    firstname.like(search_var1),
    lastname.like(search_var2)
    )

链接filter()filter_by()运算符)

query = meta.Session.query(User).\
    filter_by(firstname.like(search_var1)).\
    filter_by(lastname.like(search_var2))

使用or_()and_()not()

from sqlalchemy import and_, or_, not_

query = meta.Session.query(User).filter(
    and_(
        User.firstname.like(search_var1),
        User.lastname.like(search_var2)
    )
)

2
这些不同的方法在性能上是否存在显着差异?
Miek

2
大多数不同的方法最终都会生成相同的查询,因此在大多数情况下,您不会发现性能差异。
Asa Stallard '18

我有点困惑。该filter_by文件说,它是通过关键字参数过滤:query(Foo).filter_by(bar='baz')。这与您在以上答案中使用的语法有何关系?
电话

76

您可以简单地拨打filter多个电话:

query = meta.Session.query(User).filter(User.firstname.like(searchVar1)). \
                                 filter(User.lastname.like(searchVar2))

36
在大型mysql表上,使用多个filter()方法与在单个中使用多个条件(按or_and_)的组合之间是否存在性能差异filter
2014年

6
多个filter调用会像逻辑操作AND而不是逻辑操作OR吗?
danodonovan

12
那应该是AND
Lyman Zerga 2015年

6
我不会这么想-当您查看str(User.filter(cond1).filter(cond2))时,仅使用条件“和”生成最终的sql。
Shankar ARUL-jupyterdata.com 2015年

60

您可以使用SQLAlchemy的or_函数在多列中进行搜索(下划线必须与Python的区别or)。

这是一个例子:

from sqlalchemy import or_
query = meta.Session.query(User).filter(or_(User.firstname.like(searchVar),
                                            User.lastname.like(searchVar)))

7
您可以使用|运算符来代替or_,例如- (User.firstname.like(searchVar)) | (User.lastname.like(searchVar)),但是您应该注意|优先级,如果没有括号,当与比较运算符混合使用时,它会产生非常意想不到的结果。
丹尼尔·克鲁夫

1
不是filter.or_( case1, case 2)吗?
fedorqui'SO停止伤害

2
这是错误的,因为有关ORM的问题是问题,但链接导致表达式。
user2846569'2

1
我使用了多个过滤器语句,在此之前显着增加了延迟。我将其更改为or_,并且返回速度更快。谢谢@ gclj5
Jimmy

1

通用代码段,适用于多列。如果需要在应用程序中有条件地实现搜索功能,也可以使用此方法。

search_key = "abc"
search_args = [col.ilike('%%%s%%' % search_key) for col in ['col1', 'col2', 'col3']]
query = Query(table).filter(or_(*search_args))
session.execute(query).fetchall()

注意:%%跳过%格式化查询很重要。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.