过滤SQLAlchemy @hybrid_property不起作用

时间:2015-06-01 21:42:01

标签: sqlalchemy

我有一个SQLAlchemy模型如下,我试图过滤isActive属性。

query(PersonMedications).filter(PersonMedication.isActive==False).all()
class PersonMedication(ModelAbstract):

    __tablename__ = "personMedication"
    id = db.Column(db.Integer, primary_key=True)
    startDate = db.Column(db.Date)
    endDate = db.Column(db.Date)
    isCanceled = db.Column(db.Boolean)

    @hybrid_property
    def isActive(self):
        if self.isCanceled == True:
            return False
        elif self.endDate and self.endDate < datetime.date.today():
            return False
        elif self.startDate and self.startDate <= datetime.date.today():
            return True
        else:
            return False

我收到以下错误:

TypeError: Boolean value of this clause is not defined

从查看SQLAlchemy文档看起来我的功能似乎应该有效..我缺少什么?

http://docs.sqlalchemy.org/en/rel_1_0/orm/extensions/hybrid.html

更新

Per @ van的建议我发现我需要使用表达式函数,但似乎无法找出将逻辑串联起来的正确语法。

@isActive.expression
def isActive(cls):
    return not cls.isCanceled and cls.startDate <= func.current_date()

1 个答案:

答案 0 :(得分:1)

您还需要正确定义SQL表达式,因为sqlalchemy只能处理python表达式与SQL一对一的非常简单的情况。

在同一文档页面Defining Expression Behavior Distinct from Attribute Behavior中阅读有关该主题的更多信息。

在您的情况下,isValid == True的逻辑如下:

  • not isCancelled
  • startDate不为null,且今天等于或等于
  • endDate为null或今天之后

下面的代码用sql子句表示:

@isActive.expression
def isActive(cls):
    today = datetime.date.today()  # or replace with respective func.???

    return db.and_(
        cls.isCanceled == False,  # @note: assume it is not NULLable
        db.and_(cls.startDate != None, cls.startDate <= today),
        db.or_(cls.endDate == None, cls.endDate > today),
    )

在这种情况下,您可以执行以下查询:

# active
query(PersonMedications).filter(PersonMedication.isActive).all()
# not active
query(PersonMedications).filter(~PersonMedication.isActive).all()