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

SQLModel继承Pydantic BaseModel为何datetime字段未自动转类型?

问题:SQLModel实例化时未自动将ISO字符串转换为datetime类型

用户确认SQLModel继承自Pydantic的BaseModel(通过__mro__查看),但以下测试代码执行时类型对比失败:

from datetime import datetime
from uuid import uuid4, UUID
from sqlmodel import SQLModel, Field

class SomeModel(SQLModel, table=True):
    timestamp: datetime
    id: UUID = Field(default_factory=lambda: str(uuid4()), primary_key=True)

def test_some_model():
    m = SomeModel(**{'timestamp': datetime.utcnow().isoformat()})
    assert type(m.timestamp) == datetime

报错信息:

E       AssertionError: assert <class 'str'> == datetime

用户尝试过使用Field的default_factory等方法仍未解决,寻求FastAPI/SQLModel相关解答。


原因分析

当SQLModel设置table=True时,它会同时兼容SQLAlchemy ORM和Pydantic的特性,但默认情况下直接通过类实例化传入原始数据时,不会触发Pydantic的字段验证与类型转换——这是SQLModel为适配数据库操作性能,在ORM模型实例化流程中跳过了Pydantic的完整校验逻辑导致的。

解决方案

有两种可行的解决方式:

方式1:使用model_validate触发Pydantic校验

调用Pydantic的model_validate方法可以强制执行字段类型转换和校验,替换直接实例化的方式:

def test_some_model():
    m = SomeModel.model_validate({'timestamp': datetime.utcnow().isoformat()})
    assert type(m.timestamp) == datetime

方式2:拆分输入模型与ORM模型

如果需要明确区分数据输入校验和数据库操作模型,可以单独定义一个不设置table=True的SQLModel子类用于接收并转换数据,再映射到ORM模型:

class SomeModelCreate(SQLModel):
    timestamp: datetime

class SomeModel(SQLModel, table=True):
    timestamp: datetime
    id: UUID = Field(default_factory=uuid4, primary_key=True)

def test_some_model():
    create_data = SomeModelCreate(**{'timestamp': datetime.utcnow().isoformat()})
    m = SomeModel.model_validate(create_data)
    assert type(m.timestamp) == datetime

额外修正点

你的id字段定义存在类型不匹配问题:声明为UUID类型,但default_factory返回的是字符串(str(uuid4())),应直接返回UUID对象:

id: UUID = Field(default_factory=uuid4, primary_key=True)

内容的提问来源于stack exchange,提问作者Octavio del Ser

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:43:18