首页 > 解决方案 > Sqlalchemy 过滤器按计算的日期时间 hybrid_property

问题描述

我有一个模型处方。

from datetime import timedelta
from sqlalchemy.ext.hybrid import hybrid_property


class Prescription(db.Model):
    """ docstring """
    ID = db.column(db.Integer, primary_key=True)
    date = db.Column(db.DateTime)
    duration = db.Column(db.SmallInteger)

    @hybrid_property
    def expiration_date(self):
        # return self.date + timedelta(days=self.duration)
        return self.date + timedelta(days=7)

    @classmethod
    def actual(cls ):
        """ docstring """
        today = datetime.today()

        return cls.query.filter(Prescription.expiration_date>=today)

我只想在我的实际方法中获得实际处方,并且当我指定时

@hybrid_property
def expiration_date(self): 
    return self.date + timedelta(days=7)

一切都像魅力一样。

但是每个处方都有不同的持续时间,当我指定

@hybrid_property
def expiration_date(self): 
     return self.date + timedelta(days=self.duration)

我有一个错误

TypeError: unsupported type for timedelta days component: InstrumentedAttribute

我试着做一个像这样的小技巧

@property
def days(self):
    return int(self.duration)

但没有运气。谁能告诉一些解决方法,或者为持续时间字段创建一些惰性对象,或者以其他方式获得实际处方,通过计算的 expire_date 过滤?

标签: python-3.xsqlalchemyflask-sqlalchemy

解决方案


您可能正在尝试计算 DATEDIFF: 使用 SQLAlchemy 在 POSTGRES 中计算 DATEDIFF

在这里,is_expired将生成一个 SQL 查询部分,计算开始日期和 之间的天数差utcnow(),并将结果与self.duration

这适用于 PostgreSQL,但我尚未在其他 RDBMS 上进行测试。

from datetime import datetime
import sqlalchemy as sa


class Prescription:
    ID = db.column(db.Integer, primary_key=True)
    date = db.Column(db.DateTime)
    duration = db.Column(db.SmallInteger)

    @hybrid_property
    def is_expired(self):
        days_since_published = sa.func.trunc((
            sa.extract('epoch', datetime.utcnow()) -
            sa.extract('epoch', self.date)
        ) / 3600 / 24)

        return days_since_published >= self.duration

    @classmethod
    def active(cls):
        return cls.query.filter(is_expired=False)


推荐阅读