FastAPI中路径参数能否为列表类型?如何正确定义?
FastAPI路径参数与列表类型的问题解答
核心结论
路径参数不能直接定义为列表类型,FastAPI不支持这种用法,这也是你报错的原因。如果需要传递多个值实现批量查询,推荐用查询参数或者请求体,也可以对路径参数做自定义字符串解析,但后者不推荐。
解决方案1:使用查询参数(推荐)
把需要传递的多个SN放到查询参数里,FastAPI支持自动将多个同名查询参数解析为列表。示例代码如下:
from fastapi import FastAPI, Query from sqlalchemy import create_engine, text from sqlalchemy.orm import sessionmaker import cx_Oracle from typing import List cx_Oracle.init_oracle_client(lib_dir=r"E:\instantclient-basic-windows.x64-12.1.0.2.0\instantclient_12_1") my_database_connection = "oracle+cx_oracle://super:4567@172.16.91.132:1521/adbc" engine = create_engine(my_database_connection) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) app = FastAPI() @app.get("/multi_sn") # 查询场景用GET更合适,也可保留POST async def get_multisn(multi_sn: List[str] = Query(...)): with engine.connect() as conn: # 禁止用format拼接SQL,存在注入风险,必须用参数绑定 sql = text("SELECT * FROM your_table WHERE sn IN :sns") result = conn.execute(sql, {"sns": multi_sn}) return result.all()
调用示例:GET /multi_sn?multi_sn=SN123&multi_sn=SN456&multi_sn=SN789,FastAPI会自动把multi_sn解析为["SN123", "SN456", "SN789"]。
解决方案2:自定义路径参数解析(不推荐)
如果一定要通过路径传递,可以把多个SN用分隔符(比如逗号)拼接成字符串,然后在函数内手动分割为列表。示例:
from fastapi import FastAPI from sqlalchemy import create_engine, text from sqlalchemy.orm import sessionmaker import cx_Oracle from typing import List cx_Oracle.init_oracle_client(lib_dir=r"E:\instantclient-basic-windows.x64-12.1.0.2.0\instantclient_12_1") my_database_connection = "oracle+cx_oracle://super:4567@172.16.91.132:1521/adbc" engine = create_engine(my_database_connection) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) app = FastAPI() @app.post("/multi_sn/{multi_sn_str}") async def post_multisn(multi_sn_str: str): # 按逗号分割字符串为列表 multi_sn: List[str] = multi_sn_str.split(",") with engine.connect() as conn: sql = text("SELECT * FROM your_table WHERE sn IN :sns") result = conn.execute(sql, {"sns": multi_sn}) return result.all()
调用示例:POST /multi_sn/SN123,SN456,SN789,函数内会把路径参数分割成列表。但这种方式有局限性,比如SN本身包含逗号就会出错,所以优先用查询参数或请求体。
额外提醒
- SQL注入风险:你原代码用
format拼接SQL的做法非常危险,必须改用SQLAlchemy的text配合参数绑定(如示例中的:sns和字典参数)。 - 请求体传递列表:如果是POST请求,也可以用Pydantic模型接收列表,这是批量传递数据的常用方式:
from fastapi import FastAPI from pydantic import BaseModel from sqlalchemy import create_engine, text from sqlalchemy.orm import sessionmaker import cx_Oracle from typing import List cx_Oracle.init_oracle_client(lib_dir=r"E:\instantclient-basic-windows.x64-12.1.0.2.0\instantclient_12_1") my_database_connection = "oracle+cx_oracle://super:4567@172.16.91.132:1521/adbc" engine = create_engine(my_database_connection) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) app = FastAPI() class SNList(BaseModel): multi_sn: List[str] @app.post("/multi_sn") async def post_multisn(sn_list: SNList): with engine.connect() as conn: sql = text("SELECT * FROM your_table WHERE sn IN :sns") result = conn.execute(sql, {"sns": sn_list.multi_sn}) return result.all()
请求时在Body中传递JSON:{"multi_sn": ["SN123", "SN456"]}即可。
内容的提问来源于stack exchange,提问作者Andrew8460958
相关产品推荐
相关产品推荐

