FastAPI为何不对POST请求体进行校验?
问题解决:FastAPI + SQLModel 接口未触发参数校验错误
问题根源
直接使用带table=True的SQLModel类作为请求体时,存在两个核心问题:
- SQLModel的数据库模型默认开启ORM模式,导致Pydantic的必填字段校验未严格生效
- 默认配置允许忽略额外字段(
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
相关产品推荐
相关产品推荐

