flake8抱怨过滤子句中的布尔比较"=="

Jru*_*ruv 46 python mysql sqlalchemy flake8

我在mysql db表中有一个布尔字段.

# table model
class TestCase(Base):
    __tablename__ = 'test_cases'
    ...
    obsoleted = Column('obsoleted',  Boolean)
Run Code Online (Sandbox Code Playgroud)

要获得所有未经过时的测试用例的计数,可以像这样完成:

caseNum = session.query(TestCase).filter(TestCase.obsoleted == False).count()
print(caseNum)
Run Code Online (Sandbox Code Playgroud)

这很好,但是flake8报告了以下警告:

E712:与False的比较应该是"如果cond是假的:"或"如果不是cond:"

好的,我觉得这很有道理.所以将我的代码更改为:

caseNum = session.query(TestCase).filter(TestCase.obsoleted is False).count()
Run Code Online (Sandbox Code Playgroud)

要么

caseNum = session.query(TestCase).filter(not TestCase.obsoleted).count()
Run Code Online (Sandbox Code Playgroud)

但他们都不能奏效.结果始终为0.我认为filter子句不支持运算符"is"或"is not".有人可以告诉我如何处理这种情况.我不想禁用片状.

Mar*_*ers 63

这是因为SQLAlchemy过滤器是== False实际上有意义的少数几个地方之一.在其他地方,你应该使用它.

# noqa在该行添加注释并完成.

或者您可以使用sqlalchemy.sql.expression.false:

from sqlalchemy.sql.expression import false

TestCase.obsoleted == false()
Run Code Online (Sandbox Code Playgroud)

where false()返回会话SQL方言的正确值.有一个匹配sqlalchemy.expression.true.


avo*_*iva 44

SQL炼金术也有is_isnot你可以使用的功能.一个例子是

Model.filter(Model.deleted.is_(False))
Run Code Online (Sandbox Code Playgroud)

更多关于这里的人

  • `is` 和 `==` 在 SQLAlchemy 中是不同的,因为你不能覆盖 python 中的标识运算符(`is`)。像“Model.column is False”这样的表达式总是被评估为“False”,因为比较总是在 python 中立即发生,而不是在数据库中。比较列对象和布尔值的标识的结果始终为“False”。这会将诸如“WHERE FALSE”或“AND FALSE”之类的语句插入到您的查询中,这在大多数情况下会导致它无论如何都返回 0 行。 (2认同)

and*_*abs 15

我对使用产生什么确切的查询一看SQLAlchemy==is_数据库方言Postgresql为布尔字段:

  • 因为==我们得到:

    1. field == False 转换为 field = false
    2. field == True 转换为 field = true
    3. field == None 转换为 field IS NULL
  • 因为is_()我们得到:

    1. field.is_(False) 转换为 field IS false
    2. field.is_(True) 转换为 field IS true
    3. field.is_(None) 转换为 field IS NULL

注意: is_(not None)将评估给予的is_(bool(not None)东西is_(True)field = true所以你宁愿去isnot(None)生产 field IS NOT NULL

  • 另请注意,当您在 PostgreSQL 中使用“is”而不是“=”时,即使操作数为 NULL,您也永远不会得到 NULL 作为答案。如果任一操作数为 NULL,则 `=` 将返回 NULL。 (2认同)