FastAPI+SQLAlchemy查询报错及过滤失效问题求助
问题解决方案
1. 字典属性访问错误(已修复,同时规范请求方式)
错误原因
初始代码用body.project_ids访问字典键,但Python字典仅支持[]语法取值,因此触发AttributeError: 'dict' object has no attribute 'project_ids'。你后续改为body['project_ids']的做法是正确的,但还有一个关键问题:
GET请求不应携带请求体,HTTP规范中GET请求的请求体属于未定义行为,部分客户端、网关或代理会忽略该请求体。建议改为以下两种合规方式之一:
- 改用POST请求传递JSON数据(适合复杂参数)
- 使用查询参数传递列表(适合简单参数)
2. SQLAlchemy过滤逻辑不生效
错误原因
SQLAlchemy列对象不能直接用Python原生in关键字构建IN查询。custom_datasets.c.project_id in body['project_ids']会被Python解释为「判断列对象是否在列表中」,结果恒为False,生成的SQL条件为WHERE false,自然无法匹配数据。正确做法是使用SQLAlchemy提供的in_()方法构建IN查询条件。
修复后的完整代码
main.py
import os from sqlalchemy.orm import Session from sqlalchemy import select, create_engine from sqlalchemy.orm import sessionmaker from typing import Dict, List from fastapi import Depends, FastAPI, Body, Query # 导入sql.py中的表定义 from sql import custom_datasets app = FastAPI() # 补全数据库会话初始化代码 engine = create_engine(os.getenv("REGISTRY_CONNECTION_STRING")) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) def get_db(): # 修复会话生成逻辑:确保连接正常关闭,且仅返回一个值 if os.getenv("REGISTRY_CONNECTION_STRING"): db = SessionLocal() try: yield db finally: db.close() else: yield None # 方案1:改用POST请求传递JSON体(推荐) @app.post("/datasets/") def get_project_registry(body: Dict[str, List[str]] = Body(...), db: Session = Depends(get_db)): if not db: return [] # 使用SQLAlchemy的in_()方法构建IN查询 stmt = select(custom_datasets).where( custom_datasets.c.project_id.in_(body['project_ids']) ) res = db.execute(stmt).all() # 转换为字典列表便于返回 return [dict(row._mapping) for row in res] # 方案2:使用GET查询参数传递project_ids @app.get("/datasets/") def get_project_registry(project_ids: List[str] = Query(...), db: Session = Depends(get_db)): if not db: return [] stmt = select(custom_datasets).where( custom_datasets.c.project_id.in_(project_ids) ) res = db.execute(stmt).all() return [dict(row._mapping) for row in res]
测试请求示例
方案1(POST请求)
POST http://127.0.0.1:8009/datasets Content-Type: application/json { "project_ids": ["proj_id1"] }
方案2(GET请求,查询参数)
GET http://127.0.0.1:8009/datasets?project_ids=proj_id1
内容的提问来源于stack exchange,提问作者mascai
相关产品推荐
相关产品推荐

