You need to enable JavaScript to run this app. 使用Tortoise ORM对接PostgreSQL的Time类型字段报错问题求解
优惠活动
大模型
产品
解决方案
定价
更多

使用Tortoise ORM对接PostgreSQL的Time类型字段报错问题求解

针对Tortoise ORM适配PostgreSQL TIME类型字段的解决方案

问题根因是Tortoise ORM官方没有提供适配PostgreSQL原生TIME类型的字段,之前两种字段选型都和数据库实际字段类型不匹配:

  • 使用CharField时,PostgreSQL的TIME类型字段期望接收time类型参数,字符串类型的输入会被底层驱动尝试读取hour属性,触发str object has no attribute 'hour'错误
  • 使用DatetimeField时,虽然补全假日期可以正常写入,但查询时PostgreSQL返回的是TIME类型结果,DatetimeField的ISO8601解析逻辑无法适配time类型对象,触发解析错误

最优解决方案:自定义适配PostgreSQL TIME类型的字段

1. 实现自定义字段类

from datetime import time
from tortoise.fields import Field

class PostgreSQLTimeField(Field, time):
    # 指定数据库端字段类型为TIME
    SQL_TYPE = "TIME"

    def to_db_value(self, value: time | str, instance) -> time:
        # 入库前自动将HH:MM:SS格式字符串转为time对象
        if isinstance(value, str):
            return time.fromisoformat(value)
        return value

    def to_python_value(self, value: time | str) -> time:
        # 查询结果自动转为time对象返回
        if isinstance(value, str):
            return time.fromisoformat(value)
        return value

2. 替换模型中的对应字段

class Carb_Ratio(models.Model):
    id = fields.UUIDField(pk=True, auto_generated=True)
    client_id = fields.UUIDField()
    ratio_type = fields.CharEnumField(RatioType)
    carb_ratio = fields.DecimalField(max_digits=10, decimal_places=2)
    # 替换为自定义时间字段
    start_time = PostgreSQLTimeField()
    end_time = PostgreSQLTimeField()
    insulin_sensitivity = fields.DecimalField(max_digits=10, decimal_places=2)
    created_at = fields.DatetimeField(auto_now_add=True)

3. Pydantic模型适配

对应的Pydantic序列化/反序列化模型直接将start_time、end_time字段类型声明为time即可,前端传入HH:MM:SS格式的字符串会被Pydantic自动解析为time对象,无需额外补全假日期,读写都不会触发格式错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 06:06:03