SQLAlchemy中filter和filter_by的区别
Posted
技术标签:
【中文标题】SQLAlchemy中filter和filter_by的区别【英文标题】:Difference between filter and filter_by in SQLAlchemy 【发布时间】:2011-01-08 20:49:43 【问题描述】:谁能解释 SQLAlchemy 中 filter
和 filter_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=12345
、query(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 == expression
和keyword = expression
之间的差异。所以我们把它们分开了。
【讨论】:
我认为您关于column == expression
与keyword = expression
的观点是区分filter
和filter_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中filter和filter_by的区别
SQLAlchemy学习-8.query查找之filter()和filter_by()区别