FastAPI PUT接口返回422错误:错误选用Script模型做参数验证
问题:FastAPI PUT接口返回422错误,提示非当前模型的字段缺失
问题背景
使用FastAPI构建项目,通过Pydantic定义API输入模型,数据存储于MongoDB。调用PUT接口/scripts/attributes时收到422 Unprocessable Entity响应,错误提示缺失的字段属于Script模型,但当前接口指定的请求模型是UpdateAttributeMultiple。
相关代码
模型定义
class AttributeUpdateSpecific(BaseModel): scriptname: str attribute: str = Field(default="THREADS", description="Accepted values - THREADS, INPUT_FILE, THROUGHPUT, DURATION, JMX") value: str class UpdateAttributeMultiple(BaseModel): update: list[AttributeUpdateSpecific] class Script(BaseModel): environment: str component: str scriptname: str scriptdesc: str group: list[str] scriptstatus: str = Field(default="DONE") runid: int jmx: str variables: dict = Field(default=defaultvariables)
路由定义
@script_router.put("/attributes") async def update_individual_attributes(records: UpdateAttributeMultiple, test_db: str = Header(default=None)): updatecount = 0 records = records.model_dump()["update"] if not test_db: raise ex.empty_header_exception() async for record in records: if record["attribute"] not in ["THREADS", "DURATION", "THROUGHPUT", "INPUT_FILE", "JMX"]: raise ex.invalid_option_exception() try: updatecount += await sch.script_update_attribute(test_db, record) return { "status": "success", "description": str(updatecount) + " record(s) updated." } except ValueError: raise ex.value_exception() except Exception as exception: raise ex.internal_server_exception(exception)
请求示例
curl -X 'PUT' \ 'http://127.0.0.1:8000/scripts/attributes' \ -H 'accept: application/json' \ -H 'test-db: pcm_hpt_master' \ -H 'Content-Type: application/json' \ -d '{ "update": [ { "scriptname": "HL_TESTSCRIPT_CO_TEST", "attribute": "THREADS", "value": "150" } ] }'
错误响应
{ "detail": [ { "type": "missing", "loc": ["body", "environment"], "msg": "Field required", "input": {"update": [{"scriptname": "HL_TESTSCRIPT_CO_TEST", "attribute": "THREADS", "value": "150"}]} }, { "type": "missing", "loc": ["body", "component"], "msg": "Field required", "input": {"update": [{"scriptname": "HL_TESTSCRIPT_CO_TEST", "attribute": "THREADS", "value": "150"}]} }, { "type": "missing", "loc": ["body", "scriptdesc"], "msg": "Field required", "input": {"update": [{"scriptname": "HL_TESTSCRIPT_CO_TEST", "attribute": "THREADS", "value": "150"}]} }, { "type": "missing", "loc": ["body", "group"], "msg": "Field required", "input": {"update": [{"scriptname": "HL_TESTSCRIPT_CO_TEST", "attribute": "THREADS", "value": "150"}]} }, { "type": "missing", "loc": ["body", "runid"], "msg": "Field required", "input": {"update": [{"scriptname": "HL_TESTSCRIPT_CO_TEST", "attribute": "THREADS", "value": "150"}]} }, { "type": "missing", "loc": ["body", "jmx"], "msg": "Field required", "input": {"update": [{"scriptname": "HL_TESTSCRIPT_CO_TEST", "attribute": "THREADS", "value": "150"}]} } ] }
问题原因分析
核心原因是FastAPI匹配到了错误的路由,该路由使用Script模型作为请求体验证规则,而非当前定义的UpdateAttributeMultiple模型。具体可能场景:
- 路由路径冲突+顺序问题:同一个
script_router中存在另一个PUT路由,路径相同或匹配优先级更高,且该路由的请求体参数使用了Script模型。FastAPI按路由定义顺序匹配,若冲突路由定义在当前路由之前,会优先触发Script模型的验证。 - 模型参数误用:当前路由的请求体参数被误写为
Script模型(代码编辑笔误)。 - 中间件/依赖额外验证:项目中的中间件或依赖函数对请求体做了额外验证,错误引入
Script模型进行校验。
解决方向
- 检查
script_router中所有PUT路由,确认是否存在路径冲突且使用Script模型的路由。 - 核对当前路由的参数定义,确保请求体参数是
UpdateAttributeMultiple而非Script。 - 排查中间件和依赖函数,确认没有对该接口请求体做额外的
Script模型验证。 - 调整路由定义顺序,将当前
/attributes路由放在可能冲突的路由之前,确保优先匹配正确路由。
内容的提问来源于stack exchange,提问作者iamj
相关产品推荐
相关产品推荐

