FastAPI结合SQLModel全局查询出现ResponseValidationError问题求助
问题:FastAPI + SQLModel 查询返回数据无法通过响应模型验证
代码定义
模型定义
class DeckBase(SQLModel): name: str = Field(sa_column=Column(TEXT)) # Foreign keys owner_id: int = Field(foreign_key="player.id") class Deck(DeckBase, table=True): id: int = Field(primary_key=True) # Relationships owner: Player = Relationship(back_populates="decks") cards: List["Card"] = Relationship(back_populates="decks", link_model=DeckCards) # ManyToMany
响应模型
class DeckRead(DeckBase): id: int
异常接口实现
@router.get("/", response_model=List[DeckRead]) async def read_all(offset: int = 0, limit: int = Query(default=100, le=100), db: Session = Depends(DbContext().get_db)): decks = db.execute(select(Deck).offset(offset).limit(limit)).all() return decks
报错信息
fastapi.exceptions.ResponseValidationError: 3 validation errors: {'type': 'missing', 'loc': ('response', 0, 'name'), 'msg': 'Field required', 'input': (Deck(id=1, name='Fire deck', owner_id=1),)} {'type': 'missing', 'loc': ('response', 0, 'owner_id'), 'msg': 'Field required', 'input': (Deck(id=1, name='Fire deck', owner_id=1),)} {'type': 'missing', 'loc': ('response', 0, 'id'), 'msg': 'Field required', 'input': (Deck(id=1, name='Fire deck', owner_id=1),)}
正常运行的接口实现
@router.get("/", response_model=List[DeckRead]) async def read_all(offset: int = 0, limit: int = Query(default=100, le=100), db: Session = Depends(DbContext().get_db)): decks = db.get(Deck, 1) return [decks]
原因分析
db.execute(select(Deck)).all() 返回的是元组的列表,每个元素是包含单个Deck实例的元组(比如 (Deck(id=1, ...),)),而不是直接的Deck实例列表。Pydantic的响应模型List[DeckRead]期望接收Deck实例或可直接映射为DeckRead的对象,但元组无法被正确解析,因此抛出字段缺失的验证错误。
而db.get(Deck, 1)返回的是单个Deck实例,将其放入列表后,列表元素是符合要求的实例,因此能通过验证。
解决方案
有两种可行的修复方式:
- 使用
scalars()提取实例:
decks = db.execute(select(Deck).offset(offset).limit(limit)).scalars().all()
scalars()会直接返回查询结果中的模型实例,.all()得到实例列表,可直接返回。
- 手动从元组中提取实例:
decks = db.execute(select(Deck).offset(offset).limit(limit)).all() return [deck for deck, in decks]
通过列表推导式遍历元组列表,取出每个元组中的第一个元素(即Deck实例)。
内容的提问来源于stack exchange,提问作者Kamigaku
相关产品推荐
相关产品推荐

