SQLAlchemy中filter和filter_by的区别是什么?

bod*_*ydo 278 python sqlalchemy

任何人都可以解释SQLAlchemy 之间的区别filterfilter_by功能吗?我很困惑,不能真正看到差异.我应该使用哪一个?

Dan*_*kov 355

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

  • 等于运算符重载 (42认同)
  • 这是如何工作的?不会``db.users.name =='Ryan'`评估一次到常数然后从那时起就毫无意义了?看起来人们需要使用lambda才能工作. (19认同)
  • `type(model.column_name =='asdf')`→`sqlalchemy.sql.elements.BinaryExpression` (8认同)
  • 使用`.filter`时要小心。像`id = 12345`,`query(users).filter(id == id)`这样的查询不会在`users.id`上进行过滤。相反,它将id == id评估为True并返回所有用户。您需要使用.filter(users.id == id)(如上所述)。我今天早些时候犯了这个错误。 (5认同)

zzz*_*eek 110

我们实际上最初将这些合并在一起,即有一个类似"过滤器"的方法接受*args和**kwargs,你可以传递一个SQL表达式或关键字参数(或两者).我实际上发现它更方便,但人们总是对它感到困惑,因为它们通常仍然会克服*args和之间的差异**kwargs.所以我们将它们分开了.

  • 我认为关于`column == expression` vs.`keyword = expression`的观点是关于`filter`和`filter_by`之间区别的关键点.谢谢! (28认同)
  • 因为人们喜欢它 (15认同)
  • 使用`filter_by`的目的是能够写出jut的字段名,对于那个类,没有问题 - 而`flter`需要实际的列对象 - 这通常需要一个人输入(和读取)至少冗余的类名.所以,如果想要通过相等来过滤,那就相当方便了. (5认同)
  • 我是sqlalchemy的新手,如果这是一个愚蠢的问题,请原谅我,但filter_by()似乎不允许甚至非常简单的条件,如"price> = 100".那么,为什么还要使用filter_by()函数,如果你只能将它用于最简单的条件,比如"price = 100"? (2认同)
  • 它们之间有任何性能差异吗?我以为`filter_by`可能比`filter`快一点. (2认同)

Joh*_*rra 34

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


eno*_*mad 32

它是一种语法糖,可以加快查询编写速度.它在伪代码中的实现:

def filter_by(self, **kwargs):
    return self.filter(sql.and_(**kwargs))
Run Code Online (Sandbox Code Playgroud)

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

session.query(db.users).filter_by(name='Joe', surname='Dodson')
Run Code Online (Sandbox Code Playgroud)

顺便说一句

session.query(db.users).filter(or_(db.users.name=='Ryan', db.users.country=='England'))
Run Code Online (Sandbox Code Playgroud)

可写成

session.query(db.users).filter((db.users.name=='Ryan') | (db.users.country=='England'))
Run Code Online (Sandbox Code Playgroud)

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

Users.query.get(123)
# And even by a composite PK
Users.query.get(123, 321)
Run Code Online (Sandbox Code Playgroud)

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


ind*_*Ark 7

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

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

另一方面,filter()允许使用比较表达式(==、<、> 等),因此在需要“小于/大于”过滤时非常有用。但也可以像filter_by()一样使用(当使用 == 时)。

请记住,这两个函数对于参数类型有不同的语法。