SQLAlchemy中filter和filter_by的区别

Posted

技术标签:

【中文标题】SQLAlchemy中filter和filter_by的区别【英文标题】:Difference between filter and filter_by in SQLAlchemy 【发布时间】:2011-01-08 20:49:43 【问题描述】:

谁能解释 SQLAlchemy 中 filterfilter_by 函数之间的区别? 我应该使用哪一个?

【问题讨论】:

【参考方案1】:

filter_by 用于使用常规 kwargs 对列名进行简单查询,例如

db.users.filter_by(name='Joe')

同样可以使用filter 来完成,而不是使用 kwargs,而是使用 '==' 相等运算符,该运算符已在 db.users.name 对象上重载:

db.users.filter(db.users.name=='Joe')

您还可以使用filter 编写更强大的查询,例如:

db.users.filter(or_(db.users.name=='Ryan', db.users.country=='England'))

【讨论】:

这在后台是如何工作的? db.users.name=='Ryan' 不会评估一次为常数,然后从那时起就没有意义了吗?似乎需要使用 lambda 才能工作。 等式运算符重载 type(model.column_name == 'asdf')sqlalchemy.sql.elements.BinaryExpression 使用.filter时要小心。 id=12345query(users).filter(id == id) 之类的查询不会过滤 users.id。相反,它会将id == id 评估为True 并返回所有用户。您需要使用.filter(users.id == id)(如上所示)。我今天早些时候犯了这个错误。【参考方案2】:

filter_by 使用关键字参数,而filter 允许像filter(User.name=="john") 这样的pythonic 过滤参数

【讨论】:

【参考方案3】:

实际上,我们最初将它们合并在一起,即有一个类似“过滤器”的方法接受*args**kwargs,您可以在其中传递 SQL 表达式或关键字参数(或两者)。我实际上发现这更方便,但人们总是对此感到困惑,因为他们通常仍在克服column == expressionkeyword = expression 之间的差异。所以我们把它们分开了。

【讨论】:

我认为您关于column == expressionkeyword = expression 的观点是区分filterfilter_by 的关键。谢谢! 我是 sqlalchemy 的新手,如果这是一个愚蠢的问题,请原谅,但 filter_by() 似乎甚至不允许非常简单的条件,例如“价格 >= 100”。那么,如果您只能将其用于“price = 100”等最简单的条件,为什么还要使用 filter_by() 函数? 因为人们喜欢它 它们之间有性能差异吗?我在想filter_by 可能比filter 快一点。 使用filter_by 的重点是能够只写字段名称,对于该类,没有问题 - 而flter 需要实际的列对象 - 通常需要一个输入(并读取)至少一个冗余的类名。所以,如果要按等式过滤,还是比较方便的。【参考方案4】:

它是用于更快编写查询的语法糖。它的伪代码实现:

def filter_by(self, **kwargs):
    return self.filter(sql.and_(**kwargs))

对于 AND,您可以简单地写:

session.query(db.users).filter_by(name='Joe', surname='Dodson')

顺便说一句

session.query(db.users).filter(or_(db.users.name=='Ryan', db.users.country=='England'))

可以写成

session.query(db.users).filter((db.users.name=='Ryan') | (db.users.country=='England'))

也可以通过get方法直接PK获取对象:

Users.query.get(123)
# And even by a composite PK
Users.query.get(123, 321)

在使用get 的情况下,重要的是可以在没有来自identity map 的数据库请求的情况下返回对象,这可以用作缓存(与事务关联)

【讨论】:

这些代码示例具有误导性:声明性基表类和实例既没有过滤也没有查询方法;他们使用会话。 我从之前的答案中复制了users.filter。可能是我的错 :) query 属性是 query_property 现在它是相当标准的糖【参考方案5】:

除了之前发布的所有技术信息外,filter()filter_by() 在可用性方面存在显着差异。

第二个,filter_by(),可能仅用于通过特定说明的内容进行过滤 - 字符串或某个数值。所以只能用于类别过滤,不能用于表达式过滤。

另一方面,filter() 允许使用比较表达式(==、 等),因此它很有帮助,例如当需要“小于/大于”过滤时。但也可以像 filter_by() 一样使用(当 == 使用时)。

请记住这两个函数的参数输入语法不同。

【讨论】:

以上是关于SQLAlchemy中filter和filter_by的区别的主要内容,如果未能解决你的问题,请参考以下文章

sqlalchemy使用及序列化

SQLAlchemy中filter和filter_by的区别

SQLALchemy动态过滤器_by

SQLAlchemy学习-8.query查找之filter()和filter_by()区别

如何在 sqlalchemy 中使用 filter_by 而不是等于?

sqlalchemy filter 方法常用过滤条件