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

如何让继承自UUID的自定义类型适配Pydantic模型

问题

我们代码库中有一个继承自uuid.UUID的自定义ID类:

import uuid
from typing import Any

class ID(uuid.UUID):
    def __init__(self, *args: Any, **kwargs: Any):
        super().__init__(*args, **kwargs)

直接将其作为Pydantic模型字段(如class Model(BaseModel): id: ID)时,会触发PydanticSchemaGenerationError。由于Pydantic不支持多继承,无法让ID类同时继承BaseModel和uuid.UUID;手动实现__get_pydantic_json_schema__和__get_pydantic_core_schema__方法后仍出现错误,求正确配置方式。

正确配置方式

无需手动实现复杂的Pydantic schema方法,以下两种方案可可靠解决问题:

方案一:使用Annotated+BeforeValidator

通过验证器将输入转换为自定义ID类型,同时复用Pydantic内置的UUID校验逻辑:

import uuid
from typing import Any, Annotated
from pydantic import BaseModel, BeforeValidator

class ID(uuid.UUID):
    def __init__(self, *args: Any, **kwargs: Any):
        super().__init__(*args, **kwargs)

# 定义验证器,处理各种输入类型并转为ID实例
def validate_id(v: Any) -> ID:
    if isinstance(v, ID):
        return v
    # 对字符串、字节、UUID实例等输入,统一转为ID
    return ID(v)

# 用Annotated包装ID类型,绑定验证器
AnnotatedID = Annotated[ID, BeforeValidator(validate_id)]

# 定义Pydantic模型
class Model(BaseModel):
    id: AnnotatedID

# 测试示例
if __name__ == "__main__":
    # 支持字符串格式的UUID
    m1 = Model(id="12345678-1234-5678-1234-567812345678")
    print(type(m1.id))  # <class '__main__.ID'>
    
    # 支持原生UUID实例
    u = uuid.uuid4()
    m2 = Model(id=u)
    print(type(m2.id))  # <class '__main__.ID'>
    
    # 支持ID实例
    i = ID(uuid.uuid4())
    m3 = Model(id=i)
    print(type(m3.id))  # <class '__main__.ID'>

方案二:全局注册类型适配器

通过TypeAdapter为ID类注册全局处理逻辑,后续模型可直接使用ID类型:

import uuid
from typing import Any
from pydantic import BaseModel, TypeAdapter
from pydantic_core import core_schema

class ID(uuid.UUID):
    def __init__(self, *args: Any, **kwargs: Any):
        super().__init__(*args, **kwargs)

# 定义ID类的核心校验schema,复用UUID的校验规则
def id_core_schema() -> core_schema.CoreSchema:
    return core_schema.no_info_wrap_validator_function(
        lambda v: ID(v) if not isinstance(v, ID) else v,
        core_schema.uuid_schema(),
    )

# 注册类型适配器,让Pydantic识别ID类型
TypeAdapter(ID).validate_python = id_core_schema

# 直接使用ID类型定义模型
class Model(BaseModel):
    id: ID

# 测试示例
if __name__ == "__main__":
    m = Model(id="12345678-1234-5678-1234-567812345678")
    print(type(m.id))  # <class '__main__.ID'>

注意事项

  • 两种方案均复用Pydantic内置的UUID校验逻辑,避免重复实现校验规则
  • 方案一适合局部场景使用,方案二适合全局统一处理自定义ID类型
  • 尽量避免手动实现__get_pydantic_json_schema__和__get_pydantic_core_schema__,这类内部API易随Pydantic版本变动导致兼容问题

内容的提问来源于stack exchange,提问作者Antonio Gamiz Delgado

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 08:15:01