FastAPI如何设置可选请求参数并兼容原有接口及数据库插入逻辑
问题1:可选字段设置与接口兼容性处理
你只需要修改Pydantic入参模型,给需要设为可选的字段配置Optional类型和默认值None即可,新增字段时同样给默认值,就不会影响原有接口调用。
- 首先导入
Optional类型(Python 3.10+也可以直接用| None语法) - 修改后的入参类示例:
from typing import Optional from pydantic import BaseModel class BaseRequest(BaseModel): name: str class details(BaseRequest): age: int # 可选字段,不传默认值为None gender: Optional[str] = None # 新增测试字段,加默认值即可兼容老请求 test_field: Optional[int] = None
配置后,原有不传gender的请求也能正常通过参数校验,不会报错。
问题2:可选参数的数据库插入逻辑
不需要编写多套不同参数组合的插入语句,仅用一条插入语句即可实现,核心注意两点:
- 提前确认数据库表中对应可选字段允许存储
NULL值,如果想设默认值也可以直接在数据表字段配置默认值 - 必须替换原有字符串拼接SQL的写法,改用参数化查询:原有拼接写法不仅有SQL注入风险,还会把Python的
None转为字符串'None'存入数据库,不是真正的NULL值。
修改后的插入逻辑示例:
@router.put('/people') async def add_people(body: details): try: name, age, gender, test_field = body.name.upper(), body.age, body.gender, body.test_field # 采用参数化查询,不同数据库的参数占位符可能有区别,比如postgresql用$1 $2,mysql用%s res = await main_db_instance.fetch_rows( "INSERT INTO myDB.people (name, age, gender, test_field) VALUES ($1, $2, $3, $4) RETURNING *", name, age, gender, test_field ) return JSONResponse(jsonable_encoder(res), status_code=200) except Exception as exp: logger.exception(f'Exception while inserting the person: {exp}') return JSONResponse(status_code=500, content="Error inserting the person")
参数化查询会自动将Python的None转为数据库的NULL值存入,可选字段没有传值的情况下也能正常执行插入,不需要额外判断参数拼接SQL。
如果你不想存储NULL,想给可选字段设置业务默认值,直接在Pydantic模型里设置默认值即可,比如gender: str = '未知',不传gender时就会自动用'未知'插入数据库,不需要修改SQL逻辑。
内容的提问来源于stack exchange,提问作者Lostsoul
相关产品推荐
相关产品推荐

