SQLAlchemy中filter和filter_by的区别

417 投票
5 回答
292918 浏览
提问于 2025-04-15 18:24

有没有人能解释一下在SQLAlchemy中,filterfilter_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 == expressionkeyword = 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'))

撰写回答