python 全局检索时FastAPI验证错误

s8vozzvw  于 2024-01-05  发布在  Python
关注(0)|答案(2)|浏览(166)

我有一个问题,FastAPI与SQLModel耦合,我不明白为什么它不工作。我有以下模型:

  1. class DeckBase(SQLModel):
  2. name: str = Field(sa_column=Column(TEXT))
  3. # region Foreign keys
  4. owner_id: int = Field(foreign_key="player.id")
  5. # endregion Foreign keys
  6. class Deck(DeckBase, table=True):
  7. id: int = Field(primary_key=True)
  8. # region Relationship (access to the foreign key model)
  9. owner: Player = Relationship(back_populates="decks")
  10. cards: List["Card"] = Relationship(back_populates="decks", link_model=DeckCards) # ManyToMany
  11. # endregion Relationship (access to the foreign key model)

字符串
下面是数据库表示:


的数据
我还定义了以下函数来根据SQLModel文档检索所有deck:

  1. @router.get("/", response_model=List[DeckRead])
  2. async def read_all(offset: int = 0,
  3. limit: int = Query(default=100, le=100),
  4. db: Session = Depends(DbContext().get_db)):
  5. decks = db.execute(select(Deck).offset(offset).limit(limit)).all()
  6. return decks


其中DeckRead为:

  1. class DeckRead(DeckBase):
  2. id: int


但是当我调用路由时,我得到了这个错误:

  1. [2024-01-02 18:37:19] [ERROR ] uvicorn.error: Exception in ASGI application
  2. Traceback (most recent call last):
  3. ... (skipping the traceback)
  4. fastapi.exceptions.ResponseValidationError: 3 validation errors:
  5. {'type': 'missing', 'loc': ('response', 0, 'name'), 'msg': 'Field required', 'input': (Deck(id=1, name='Fire deck', owner_id=1),), 'url': 'https://errors.pydantic.dev/2.5/v/missing'}
  6. {'type': 'missing', 'loc': ('response', 0, 'owner_id'), 'msg': 'Field required', 'input': (Deck(id=1, name='Fire deck', owner_id=1),), 'url': 'https://errors.pydantic.dev/2.5/v/missing'}
  7. {'type': 'missing', 'loc': ('response', 0, 'id'), 'msg': 'Field required', 'input': (Deck(id=1, name='Fire deck', owner_id=1),), 'url': 'https://errors.pydantic.dev/2.5/v/missing'}


为什么它不起作用?还有,让我烦恼的是,做下面的代码工作得很好:

  1. @router.get("/", response_model=List[DeckRead])
  2. async def read_all(offset: int = 0,
  3. limit: int = Query(default=100, le=100),
  4. db: Session = Depends(DbContext().get_db)):
  5. decks = db.get(Deck, 1)
  6. return [decks]


看起来all()函数返回了fastapi无法理解的内容
谢谢你,谢谢

guicsvcw

guicsvcw1#

SQLModel使用一个特殊的exec函数,它 Package 了来自SQLAlchemy的底层execute

  1. decks = db.exec(select(Deck).offset(offset).limit(limit)).all()

字符串
应该可以
这样做的原因是SQLALchemy的execute将返回一个元组列表(因为您可以select多个模型),除非您将.scalars()添加到查询中。SQLModel有一个特殊的函数,用于只select一个模型的特定情况。

huus2vyu

huus2vyu2#

问题似乎与响应模型和数据库返回的实际数据不匹配有关。read_all函数试图返回Deck示例列表,但response_model被指定为List[DeckRead]。由于DeckRead包含一个额外的字段(id),FastAPI期望响应数据具有此字段,导致验证错误。
试试这个:

  1. @router.get("/", response_model=List[Deck])

字符串

相关问题