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

如何为Pydantic拆分式时间戳模型添加Schema描述及自定义日期验证?

问题与解决方案

问题背景

我已创建一个继承自RootModel的Pydantic模型TimestampWithSplit,可将形如{ "date": "2021-07-01", "time": "12:36:23" }的JSON对象解析为datetime(2021, 7, 1, 12, 36, 23),同时能生成基础JSON Schema。现有代码如下:

from datetime import datetime
from typing import Any, Type
from pydantic import RootModel
from pydantic_core import core_schema
from pydantic_core.core_schema import GetCoreSchemaHandler

class TimestampWithSplit(RootModel):
    root: datetime

    @classmethod
    def __get_pydantic_core_schema__(
        cls, source: Type[Any], handler: GetCoreSchemaHandler
    ) -> core_schema.CoreSchema:
        return core_schema.chain_schema(
            [
                core_schema.typed_dict_schema(
                    {
                        "date": core_schema.typed_dict_field(core_schema.date_schema()),
                        "time": core_schema.typed_dict_field(core_schema.time_schema()),
                    }
                ),
                core_schema.no_info_plain_validator_function(cls.validate_to_datetime),
            ]
        )

    @staticmethod
    def validate_to_datetime(value: dict) -> datetime:
        return datetime.combine(value["date"], value["time"])

需要完成两项优化:

  1. 为生成的JSON Schema的date和time字段添加描述信息
  2. 为date字段添加自定义验证,支持解析单数字的日/月(如2021-7-1)

解决方案

你的实现路径是正确的,通过__get_pydantic_core_schema__自定义核心Schema是实现这类需求的标准方式。以下是整合两项需求后的完整代码:

完整实现代码

from datetime import datetime
from typing import Any, Type
from pydantic import RootModel
from pydantic_core import core_schema
from pydantic_core.core_schema import GetCoreSchemaHandler

class TimestampWithSplit(RootModel):
    root: datetime

    @classmethod
    def __get_pydantic_core_schema__(
        cls, source: Type[Any], handler: GetCoreSchemaHandler
    ) -> core_schema.CoreSchema:
        # 1. 构建带自定义验证和Schema描述的date字段Schema
        def validate_custom_date(value: str) -> datetime.date:
            # 支持两种日期格式:带前导零和不带前导零
            for fmt in ("%Y-%m-%d", "%Y-%-m-%-d"):
                try:
                    return datetime.strptime(value, fmt).date()
                except ValueError:
                    continue
            raise ValueError(f"无效日期格式: {value},请使用YYYY-MM-DD或YYYY-M-D格式")

        custom_date_schema = core_schema.no_info_plain_validator_function(validate_custom_date)
        custom_date_schema = core_schema.with_json_schema(
            custom_date_schema,
            {
                "format": "date",
                "title": "Date",
                "type": "string",
                "description": "ISO格式日期,支持YYYY-MM-DD或YYYY-M-D格式"
            }
        )

        # 2. 构建带Schema描述的time字段Schema
        custom_time_schema = core_schema.with_json_schema(
            core_schema.time_schema(),
            {
                "format": "time",
                "title": "Time",
                "type": "string",
                "description": "ISO格式时间,例如HH:MM:SS"
            }
        )

        # 组装最终的核心Schema
        return core_schema.chain_schema(
            [
                core_schema.typed_dict_schema(
                    {
                        "date": core_schema.typed_dict_field(custom_date_schema),
                        "time": core_schema.typed_dict_field(custom_time_schema),
                    }
                ),
                core_schema.no_info_plain_validator_function(cls.validate_to_datetime),
            ]
        )

    @staticmethod
    def validate_to_datetime(value: dict) -> datetime:
        return datetime.combine(value["date"], value["time"])

关键实现说明

  1. 添加JSON Schema描述

    • 使用core_schema.with_json_schema()方法,为每个字段的核心Schema附加自定义JSON Schema元数据,其中包含description字段,满足你对Schema的定制需求。
    • 对于time字段,直接基于内置的time_schema()添加描述即可;对于date字段,先绑定自定义验证器,再添加Schema描述。
  2. 自定义日期验证逻辑

    • 在__get_pydantic_core_schema__内部定义validate_custom_date函数,尝试多种日期格式解析(带前导零和不带前导零的格式),确保支持2021-7-1这类输入。
    • 将验证器包装为core_schema.no_info_plain_validator_function,作为date字段的核心验证逻辑。

效果验证

# 测试解析单数字月日的JSON
json_input = '{"date": "2021-7-1", "time": "12:36:23"}'
result = TimestampWithSplit.model_validate_json(json_input)
print(result.root)  # 输出: 2021-07-01 12:36:23

# 查看生成的JSON Schema
schema = TimestampWithSplit.model_json_schema()
print(schema["properties"]["date"]["description"])  # 输出: ISO格式日期,支持YYYY-MM-DD或YYYY-M-D格式
print(schema["properties"]["time"]["description"])  # 输出: ISO格式时间,例如HH:MM:SS

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 00:27:09