SQLAlchemy中filter和filter_by的区别
有没有人能解释一下在SQLAlchemy中,filter
和filter_by
这两个函数有什么区别?我应该用哪个呢?
5 个回答
71
这是一种让查询写起来更快的语法糖。它的实现可以用伪代码表示:
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
中返回,而不需要再请求数据库,这个identity map
可以用作缓存(与事务相关联)。
140
其实我们最开始是把这些功能合在一起的,也就是说有一个类似“过滤”的方法,可以接受 *args
和 **kwargs
,你可以传入一个 SQL 表达式或者关键字参数(或者两者都可以)。我个人觉得这样用起来方便多了,但很多人总是搞不清楚,因为他们通常还在适应 column == expression
和 keyword = expression
之间的区别。所以我们就把它们分开了。
543
filter_by
是用来对列名进行简单查询的,可以通过常规的关键字参数来实现,比如:
db.users.filter_by(name='Joe')
同样的功能也可以用 filter
来实现,不过这次不使用关键字参数,而是用 '==' 这个等于运算符,这个运算符已经在 db.users.name
对象上进行了重载:
db.users.filter(db.users.name=='Joe')
你还可以使用 filter
写出更复杂的查询,比如像这样的表达式:
db.users.filter(or_(db.users.name=='Ryan', db.users.country=='England'))