【问题标题】:Difference between filter and filter_by in SQLAlchemySQLAlchemy中filter和filter_by的区别
【发布时间】:2011-01-08 20:49:43
【问题描述】:

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

【问题讨论】:

    标签: python sqlalchemy


    【解决方案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=12345query(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 == expressionkeyword = expression 之间的差异。所以我们把它们分开了。

      【讨论】:

      • 我认为您关于column == expressionkeyword = expression 的观点是区分filterfilter_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() 一样使用(当 == 使用时)。

      请记住这两个函数的参数输入语法不同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-02
        • 2015-07-05
        • 2020-07-30
        • 1970-01-01
        • 1970-01-01
        • 2018-11-09
        • 1970-01-01
        • 2015-08-24
        相关资源
        最近更新 更多