You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLAlchemy添加混合属性:datetime与数值字段求和查询报错求助

问题描述

我想在SQLAlchemy模型中计算一个结合两个现有字段的属性,并将其用于查询参数。模型定义如下:

class Booking(BaseORMModel):
    start: Mapped[datetime] = mapped_column(TIMESTAMP(timezone=True))
    duration_minutes: Mapped[int] = mapped_column(Numeric)

我需要动态计算ended_at字段,其值为start与duration_minutes对应的时长之和。我的实现尝试如下:

class Booking(BaseORMModel):
    ...
    @hybrid_property
    def ended_at(self):
        return self.start + timedelta(minutes=self.duration_minutes)

    @ended_at.expression
    def ended_at(cls):
        duration_interval = func.cast(concat(cls.duration_minutes, ' MINUTES'), INTERVAL)
        ended_at = func.sum(cls.start + duration_interval)
        return ended_at

查询语句:

query = query.where(Booking.ended_at < now)

执行时出现如下错误:

sqlalchemy.exc.ProgrammingError: (psycopg.errors.UndefinedFunction) function sum(timestamp with time zone) does not exist
解决方案

错误根源是误用了func.sum()——这个函数用于多行数据的聚合求和,而此处仅需为每行记录的start时间加上对应分钟间隔,完全不需要聚合操作,直接返回时间相加的表达式即可。

修正后的完整模型实现:

from datetime import timedelta
from sqlalchemy import func, cast, Interval, TIMESTAMP
from sqlalchemy.orm import Mapped, mapped_column
from your_base_model import BaseORMModel  # 替换为实际的基类导入

class Booking(BaseORMModel):
    start: Mapped[datetime] = mapped_column(TIMESTAMP(timezone=True))
    duration_minutes: Mapped[int] = mapped_column(Numeric)

    @hybrid_property
    def ended_at(self):
        return self.start + timedelta(minutes=self.duration_minutes)

    @ended_at.expression
    def ended_at(cls):
        # 将数值类型的duration_minutes转为分钟间隔,与start时间相加
        return cls.start + cast(cls.duration_minutes, Interval(minutes=True))

针对PostgreSQL,还可以用更贴合数据库原生特性的写法:

@ended_at.expression
def ended_at(cls):
    # 利用PostgreSQL的make_interval函数直接生成分钟间隔
    return cls.start + func.make_interval(minutes=cls.duration_minutes)

修正后执行原查询语句,即可正常筛选出ended_at小于指定时间的记录。

内容的提问来源于stack exchange,提问作者Christian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:30:12