如何使用FastAPI & Pydantic返回用户平均等级值
实现思路与代码修改方案
1. 数据库查询逻辑修改
假设等级数据存在Level表中,与Organizer的user_id关联,查询时用SQLAlchemy的func.avg()直接计算平均值,替代原查询等级数组的逻辑:
from sqlalchemy import func # 查询指定user_id的organizer及其对应等级的平均值 organizer_data = db.query( Organizer, func.avg(Level.level).label("average_level") ).join(Level, Organizer.user_id == Level.user_id) .filter(Organizer.user_id == target_user_id) .group_by(Organizer.id) .first()
2. 调整Schema字段定义
将schema.py中Organizer响应模型的averageLevel字段类型从数组(如List[int])改为数值类型:
from pydantic import BaseModel from typing import Optional class OrganizerResponse(BaseModel): # 其他字段保持不变 averageLevel: Optional[float] = None # 替换原数组类型定义 class Config: orm_mode = True
3. 接口返回逻辑适配
在API处理函数中,把计算得到的平均值赋值给响应模型的对应字段:
@app.get("/organizer/{user_id}", response_model=OrganizerResponse) def get_organizer(user_id: int, db: Session = Depends(get_db)): organizer, avg_level = db.query( Organizer, func.avg(Level.level).label("average_level") ).join(Level, Organizer.user_id == Level.user_id) .filter(Organizer.user_id == user_id) .group_by(Organizer.id) .first() if not organizer: raise HTTPException(status_code=404, detail="Organizer not found") # 将平均值传入响应模型 return OrganizerResponse( **organizer.__dict__, averageLevel=avg_level or 0 # 无等级数据时设默认值0 )
补充说明
- 若需要整数形式的平均值,可改用
func.round(func.avg(Level.level))或直接将avg_level转换为int类型 - 若
Organizer与Level是一对多关联,确保join和group_by的逻辑符合你的数据结构
内容的提问来源于stack exchange,提问作者Mat
相关产品推荐
相关产品推荐

