如何在FastAPI中返回字符串列表而非Pydantic对象列表?
问题
我正尝试通过Pydantic模型在FastAPI中返回条目列表。当前我的路由代码如下:
from typing import List from fastapi import Depends from sqlalchemy.orm.session import Session ... @router.get('/search-job-types', response_model=List[JobTypeDisplay]) def job_types(search_word: str, db: Session = Depends(get_db)): return db_dims.search_job_types(search_word, db) # db_dims: def search_job_types(search_word: str, db: Session): s_word = search_word.capitalize() s_word2 = "%{}%".format(s_word) all = db.query(DbJobType).filter(DbJobType.name.like(s_word2)).all() # list_jobs = [] # for item in all: # list_jobs.append(item.name) return all
对应的Pydantic模型定义如下:
from pydantic import BaseModel class JobTypeDisplay(BaseModel): name: str class Config: orm_mode = True
目前接口返回的是包含name字段的对象列表:
[ { "name": "Something3" }, { "name": "Somethin2" }, { "name": "Something1" } ]
但我期望返回纯字符串列表:
["Something3", "Somethin2", "Something1"]
请问实现该需求的最优方式是什么,是否必须使用循环?
解决方案
方法1:直接从数据库查询name字段(最优)
不用查询整个DbJobType对象,直接只获取name列,这样返回的就是字符串列表,不需要后续处理,效率最高。
修改db_dims里的search_job_types函数:
def search_job_types(search_word: str, db: Session): s_word = search_word.capitalize() s_word2 = "%{}%".format(s_word) # 只查询name字段,scalars()返回单个值的迭代器,再转成列表 names = db.query(DbJobType.name).filter(DbJobType.name.like(s_word2)).scalars().all() return names
然后修改路由的response_model为List[str],无需再用JobTypeDisplay模型:
@router.get('/search-job-types', response_model=List[str]) def job_types(search_word: str, db: Session = Depends(get_db)): return db_dims.search_job_types(search_word, db)
方法2:在路由层用列表推导式转换结果
如果必须保留原查询逻辑(即查询整个DbJobType对象),可以用列表推导式代替显式循环,写法更简洁:
@router.get('/search-job-types', response_model=List[str]) def job_types(search_word: str, db: Session = Depends(get_db)): job_type_objects = db_dims.search_job_types(search_word, db) return [item.name for item in job_type_objects]
同样需要把response_model改为List[str]。
结论
不需要使用显式循环,列表推导式或数据库层面直接查询字段都是更简洁高效的方式。其中方法1是最优解,它减少了数据库传输的数据量,也省去了后续的对象转换步骤。
内容的提问来源于stack exchange,提问作者Tomas Am
相关产品推荐
相关产品推荐

