FastAPI结合Peewee ORM使用select()触发递归深度超限错误
问题描述
我正在为Rest API编写getAll控制器,代码如下:
@app.get("/api/note") async def getAll(): return Note.select()
但发起请求时返回错误,错误信息:
File "C:\Users\Luciano\AppData\Local\Programs\Python\Python310\lib\site-packages\fastapi\encoders.py", line 161, in jsonable_encoder return jsonable_encoder( File "C:\Users\Luciano\AppData\Local\Programs\Python\Python310\lib\site-packages\fastapi\encoders.py", line 117, in jsonable_encoder encoded_value = jsonable_encoder( File "C:\Users\Luciano\AppData\Local\Programs\Python\Python310\lib\site-packages\fastapi\encoders.py", line 148, in jsonable_encoder if isinstance(obj, classes_tuple): File "C:\Users\Luciano\AppData\Local\Programs\Python\Python310\lib\abc.py", line 119, in __instancecheck__ return _abc_instancecheck(cls, instance) RecursionError: maximum recursion depth exceeded in comparison
Note模型无问题,其他控制器(如下方更新控制器)可正常工作:
# 这个完全正常 @app.put("/api/note/{id}") async def updateByID(note: NoteSchema, id): data = { "id": id, "title": note.title, "description": note.description } Note.update({ Note.title: data.get('title'), Note.description: data.get('description'), }).where(Note.id == id).execute() return data
我还尝试过使用Note.select().get()或Note.select().where(True).get(),但仍无法解决问题。
解决方法
问题核心是FastAPI无法直接序列化Peewee的查询集对象,Note.select()返回的是ModelSelect类型的查询集,不是可直接JSON序列化的数据结构,递归错误是序列化器解析查询集内部关联时陷入循环导致的。
你需要把查询结果转换成FastAPI能处理的格式,以下是两种可行方案:
方案1:转换为字典列表
利用Peewee自带的dicts()方法,将每个模型实例转为字典后返回:
@app.get("/api/note") async def getAll(): return list(Note.select().dicts())
方案2:使用Pydantic模型序列化
如果已有NoteSchema,可以将查询到的每个Note实例转为Pydantic模型对象,同时指定响应模型确保输出格式:
@app.get("/api/note", response_model=list[NoteSchema]) async def getAll(): notes = Note.select() return [NoteSchema.from_orm(note) for note in notes]
为什么update接口能正常工作?
因为update接口返回的是手动构造的普通字典data,FastAPI可以直接识别并完成序列化,而非返回Peewee的模型或查询集对象。
内容的提问来源于stack exchange,提问作者Lullaby
相关产品推荐
相关产品推荐

