FastAPI返回SQLAlchemy查询结果时丢失总台词数字段问题
问题解决:FastAPI返回SQLAlchemy聚合结果丢失字段
核心原因
原查询中func.count(models.Script.detail)属于匿名聚合字段,SQLAlchemy返回的Row对象里该结果没有明确属性名,FastAPI序列化时仅识别有命名的模型字段(如actor),导致聚合数值被忽略。
解决方案
方案1:给聚合字段加别名并转为字典列表
修改查询逻辑,为聚合结果添加明确字段名,再将结果转为字典列表确保序列化结构清晰:
def get_actors(db: Session, detailed: bool = False) -> list[dict]: """Return a list of actors and their total lines from the show""" if not detailed: query = ( db.query( models.Script.actor, func.count(models.Script.detail).label('total_lines') # 为聚合结果添加别名 ) .filter(models.Script.actor.isnot(None)) .group_by(models.Script.actor) .order_by(func.count(models.Script.detail).desc()) ) # 转换为字典列表,明确键值对应关系 actors_list = [{"actor": item.actor, "total_lines": item.total_lines} for item in query] print("ACTORS LIST:", actors_list) return actors_list ...
方案2:使用Pydantic模型规范返回结构(更推荐)
定义Pydantic模型约束返回数据结构,FastAPI会自动完成ORM对象到JSON的序列化:
from pydantic import BaseModel # 定义返回数据模型 class ActorLineCount(BaseModel): actor: str total_lines: int class Config: orm_mode = True # 支持直接从SQLAlchemy Row/Model对象序列化 def get_actors(db: Session, detailed: bool = False) -> list[ActorLineCount]: """Return a list of actors and their total lines from the show""" if not detailed: query = ( db.query( models.Script.actor, func.count(models.Script.detail).label('total_lines') ) .filter(models.Script.actor.isnot(None)) .group_by(models.Script.actor) .order_by(func.count(models.Script.detail).desc()) ) actors_list = query.all() print("ACTORS LIST:", actors_list) return actors_list ...
额外修正
原函数的返回类型注解list[str]不符合实际返回结构,需改为list[dict]或list[ActorLineCount],避免类型提示错误。
内容的提问来源于stack exchange,提问作者Vaiterius
相关产品推荐
相关产品推荐

