FastAPI + SQLModel使用where过滤查询失效问题求助
问题
使用FastAPI结合SQLModel开发应用,已完成数据库配置、模型定义及路由编写。目前可成功插入数据,也能正常查询所有记录和按ID查询记录,但调用/creator/display?data=JohnDoe接口按display字段查询时,返回的是模型默认值而非目标数据。
查看生成的SQL语句,发现where条件使用了参数占位符:display_1,而非预期的'JohnDoe'。
问题分析
核心错误出在/display路由的查询逻辑:
query = select(Creator).where(Creator.display == f"'{data}'")
手动给data添加单引号后,SQLModel会把整个带引号的字符串'JohnDoe'当作完整参数值处理,生成的SQL会变成WHERE display = :display_1,而参数display_1的实际值是包含单引号的'JohnDoe',和数据库中存储的无引号值JohnDoe不匹配,导致查询不到目标数据,最终返回模型默认值。
另外,session.exec(query)返回的是结果集对象,直接返回会引发序列化错误,需明确获取单条或多条记录。
修复方案
修改routers/creators.py中的creator_by_display函数:
@router.get( "/display", response_model=CreatorRead, ) async def creator_by_display( data: str, session: Session = Depends(get_session), ): query = select(Creator).where(Creator.display == data) # 移除手动添加的单引号 creator = session.exec(query).first() # 获取单条匹配记录 if not creator: raise HTTPException(status_code=404, detail="Creator not found") return creator
补充说明
- SQLModel会自动处理参数的转义和引号,手动添加单引号不仅多余,还会破坏查询逻辑,同时ORM的参数化查询能有效防止SQL注入。
- 若需支持查询多个匹配
display的记录,可调整响应模型和结果获取方式:
@router.get( "/display", response_model=List[CreatorRead], ) async def creator_by_display( data: str, session: Session = Depends(get_session), ): query = select(Creator).where(Creator.display == data) creators = session.exec(query).all() if not creators: raise HTTPException(status_code=404, detail="No creators found with this display name") return creators
内容的提问来源于stack exchange,提问作者BeardedTek
相关产品推荐
相关产品推荐

