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

FastAPI为何不对POST请求体进行校验?

问题解决:FastAPI + SQLModel 接口未触发参数校验错误

问题根源

直接使用带table=True的SQLModel类作为请求体时,存在两个核心问题:

  1. SQLModel的数据库模型默认开启ORM模式,导致Pydantic的必填字段校验未严格生效
  2. 默认配置允许忽略额外字段(extra="ignore"),所以传入未定义字段不会触发错误

解决方案

1. 分离请求模型与数据库模型

创建专门的请求模型用于接收请求校验,数据库模型专注于数据库映射,避免ORM模式干扰请求校验逻辑。

修改模型代码:

from sqlmodel import SQLModel, Field

# 仅用于请求校验的模型,不关联数据库表
class JobCreate(SQLModel):
    job_id: int
    title: str
    start_time: str
    end_time: str | None = None
    pipeline_id: int
    prj_path: str
    branch_tag: str
    user: str
    status: str
    log: str = ""
    result: str = ""

    # 配置禁止额外字段,触发422错误
    model_config = {"extra": "forbid"}

# 数据库映射模型,继承请求模型并添加表配置
class Job(JobCreate, table=True):
    # 重写字段添加外键约束
    pipeline_id: int = Field(foreign_key="pipeline.pipeline_id")

2. 更新接口使用请求模型

在POST接口中使用JobCreate作为请求体参数,保证校验逻辑生效,同时保持返回数据库模型。

修改控制器代码:

from fastapi import APIRouter
from models.job import Job, JobCreate

job_router = APIRouter(prefix="/job", tags=["Jobs"])

@job_router.post("/", status_code=201, response_model=Job)
async def add_job(job: JobCreate):
    # 将请求模型转换为数据库模型
    db_job = Job.model_validate(job)
    job = await c.insert_job(db_job)
    return job

3. 验证效果

  • 传入仅含{"job_id": 0}的请求时,会触发422错误,提示title、start_time等必填字段缺失
  • 传入带额外字段(如{"job_id":0, "title":"test", "start_time":"2024-01-01", "extra_field":"xxx"})的请求时,会触发422错误,提示额外字段不被允许

内容的提问来源于stack exchange,提问作者Matteo Manzoni - DDX

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:07:38