【问题标题】:Filtering on SQLAlchemy @hybrid_property not working过滤 SQLAlchemy @hybrid_property 不起作用
【发布时间】:2015-06-01 21:42:00
【问题描述】:

我有一个 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

更新

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

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

【问题讨论】:

    标签: sqlalchemy


    【解决方案1】:

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

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

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

    • 不是取消
    • 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()
    

    【讨论】:

    • 谢谢范。我更新了帖子,似乎无法弄清楚如何将布尔逻辑串在一起成为 SQLAlchme 理解的方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    相关资源
    最近更新 更多