如何避免列表推导式,让Pydantic自动序列化SQLAlchemy多行结果?
我需要序列化SQLAlchemy查询返回的多行结果,所有API需返回固定结构的JSON(包含status_code、data、message、success字段),其中data为对应实体的Pydantic模型列表。当前通过列表推导式[UserSerializer.from_orm(user) for user in users]完成转换,想知道有没有无需手动编写推导式的方法,让Pydantic/SQLModel/FastAPI自动完成序列化过程。
解决方案
方法1:利用Pydantic自动处理可迭代ORM对象集合
Pydantic支持直接将可迭代的ORM实例集合传入响应模型,配合List[UserSerializer]类型的字段定义,自动完成批量序列化,无需手动写列表推导式。
修改你的API实现:
@router.get("/library/user/{username}", response_model=UserApiResponse) async def get_user_by_username(username: str): try: users = User.select_user(username=username) except RowNotFound: return {"success": False, "status_code": 404, "message": "user not found"} # 直接传入users集合,Pydantic自动遍历并调用UserSerializer.from_orm处理每个元素 return UserApiResponse(data=users)
核心逻辑:UserApiResponse的data字段定义为List[UserSerializer],Pydantic会自动识别集合类型,逐个调用from_orm完成转换。
方法2:让序列化模型继承SQLModel(适配SQLModel场景)
由于你已经使用SQLModel,让序列化模型继承SQLModel而非BaseModel,SQLModel对ORM对象的序列化支持更原生,同样可以自动处理集合:
修改UserSerializer定义:
from sqlmodel import SQLModel class UserSerializer(SQLModel): username: str role: str functionalities: List[str] @classmethod def from_orm(cls, obj: User) -> "UserSerializer": return cls( username=obj.username, role=obj.role.name, functionalities=obj.role.functions, )
之后同样直接传入users集合给UserApiResponse(data=users)即可,SQLModel会自动完成批量序列化。
方法3:依赖FastAPI响应模型自动绑定
如果查询结果是可迭代的ORM实例集合(比如SQLAlchemy的Result/Query对象、列表),FastAPI在处理response_model时,会自动根据模型定义完成序列化。直接返回包含data: users的字典即可:
return {"data": users}
FastAPI会识别data对应的List[UserSerializer]类型,自动遍历集合并调用from_orm转换每个元素。
注意事项
- 确保
users是可迭代对象(如SQLAlchemy查询结果、列表),否则无法自动遍历转换。 - 如果
User.select_user返回单个对象而非集合,需调整UserApiResponse的data字段类型为Optional[UserSerializer],或确保查询方法返回集合类型。
内容的提问来源于stack exchange,提问作者GarbageTime

