无法在 sqlalchemy 中对 @hybrid_property 应用过滤器

hbr*_*rls 5 sqlalchemy

代码很简单:

Class A(Base):
    status = Columns(Integer)

    @hybrid_property
    def is_ok(self):
        return self.status > 0
Run Code Online (Sandbox Code Playgroud)

session.query(A).filter(A.is_ok).all()
Run Code Online (Sandbox Code Playgroud)

将引发异常:TypeError: Boolean value of this clause is not defined

我试过了print result[0].is_ok, type(result[0].is_ok)。它是True <type 'bool'>

那么我怎样才能过滤基于 hybrid_property


我的答案

在@van 的帮助下,我知道该怎么做。

argfilter(*criterion)应该是一个SQL 表达式对象。我曾经认为它需要一个布尔值作为参数,不是

条件是适用于选择的 WHERE 子句的任何 SQL 表达式对象。字符串表达式通过 text() 构造被强制转换为 SQL 表达式构造。

代码告诉:

# wrong code:
@is_ok.expression
def is_ok(self):
    return self.status > 30 and self.status < 90

# correct code:
from sqlalchemy.sql import and_
@is_ok.expression
def is_ok(self):
    return and_(self.status > 30, self.status < 90).label('is_ok')
Run Code Online (Sandbox Code Playgroud)

van*_*van 3

添加自定义表达式。下面使用CASE语句,但IF如果您的数据库支持它,您也可以使用它:

@is_ok.expression
def is_ok(cls):
    return case([(cls.status > 0, True)], else_=False).label("is_ok")
Run Code Online (Sandbox Code Playgroud)

请参阅Defining Expression Behavior Distinct from Attribute Behavior文档以获取更多信息。