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

FastAPI中Pydantic无法序列化数据问题求助

FastAPI中Pydantic序列化失败问题解决

问题现象

  • 路由配置response_model=List[SProject]时,触发ResponseValidationError,提示id、title字段缺失
  • 移除response_model后,接口返回嵌套字典列表,每个元素包含Project键,对应ORM对象的序列化内容

相关代码

路由代码

@router.get('', response_model=List[SProject])
async def get_all_projects():
    return await ProjectDAO.find_all()

ORM模型

class ProjectProfile(Base):
    __tablename__ = 'project_profile'
    project_id = Column(ForeignKey('projects.id'), primary_key=True)
    profile_id = Column(ForeignKey('profiles.id'), primary_key=True)
    role = Column('role', String)
    is_creator = Column(Boolean, default=False)


class Project(Base):
    __tablename__ = 'projects'

    id = Column(Integer, primary_key=True)
    title = Column(String, nullable=False)
    description = Column(String)
    created_at = Column(Date, default=datetime.utcnow())

    profiles = relationship('Profile', secondary='project_profile',
                        back_populates='projects')

Pydantic Schema

class SProject(BaseModel):
    id: int
    title: str
    description: Optional[str] = None
    created_at: Optional[datetime] = None

    class Config:
        orm_mode = True

原DAO层代码

class ProjectDAO(BaseDAO):
    model = Project

    @classmethod
    async def find_all(cls):
        async with async_session_maker() as session:
            query = select(cls.model)
            result = await session.execute(query)
            return result.mappings().all()

错误详情

fastapi.exceptions.ResponseValidationError: 2 validation errors:
    {'type': 'missing', 'loc': ('response', 0, 'id'), 'msg': 'Field required', 'input': {'Project': <app.projects.models.Project object at 0x7f6d5dc95e40>}}
    {'type': 'missing', 'loc': ('response', 0, 'title'), 'msg': 'Field required', 'input': {'Project': <app.projects.models.Project object at 0x7f6d5dc95e40>}}

移除响应模型后的正常响应

[
  {
    "Project": {
      "created_at": "2023-09-20",
      "id": 2,
      "description": "sdadasd",
      "title": "dasd"
    }
  }
]

问题根源

DAO层使用result.mappings().all()返回的是映射字典列表,每个字典以模型名Project为键,对应的值是ORM对象。而Pydantic的SProject开启orm_mode=True后,期望直接接收ORM对象解析,无法从{"Project": ORM对象}的嵌套结构中提取id、title等字段,导致验证失败。

解决方案

修改DAO层,使用scalars().all()替代mappings().all(),直接返回ORM对象列表:

class ProjectDAO(BaseDAO):
    model = Project

    @classmethod
    async def find_all(cls):
        async with async_session_maker() as session:
            query = select(cls.model)
            result = await session.execute(query)
            # 直接提取ORM对象列表
            return result.scalars().all()

验证结果

修改后,路由返回的ORM对象列表会被Pydantic正确序列化,符合List[SProject]的响应模型要求,不再抛出验证错误,接口返回结构与SProject定义一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 19:40:21