问题:SQLAlchemy中filter和filter_by之间的区别

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

Could anyone explain the difference between filter and filter_by functions in SQLAlchemy? Which one should I be using?


回答 0

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

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'))

filter_by is used for simple queries on the column names using regular kwargs, like

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

The same can be accomplished with filter, not using kwargs, but instead using the ‘==’ equality operator, which has been overloaded on the db.users.name object:

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

You can also write more powerful queries using filter, such as expressions like:

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


回答 1

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

We actually had these merged together originally, i.e. there was a “filter”-like method that accepted *args and **kwargs, where you could pass a SQL expression or keyword arguments (or both). I actually find that a lot more convenient, but people were always confused by it, since they’re usually still getting over the difference between column == expression and keyword = expression. So we split them up.


回答 2

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

filter_by uses keyword arguments, whereas filter allows pythonic filtering arguments like filter(User.name=="john")


回答 3

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

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'))

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

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

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

It is a syntax sugar for faster query writing. Its implementation in pseudocode:

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

For AND you can simply write:

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

btw

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

can be written as

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

Also you can get object directly by PK via get method:

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

When using get case its important that object can be returned without database request from identity map which can be used as cache(associated with transaction)


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。