FastAPI中间件用Depends获取数据库会话报错:'Depends'无'add'属性
错误原因分析
你遇到的AttributeError: 'Depends' object has no attribute 'add'是因为FastAPI的HTTP中间件函数不支持直接通过参数声明Depends注入依赖。中间件的参数列表只能包含Request和call_next,你在中间件里写的db: Session = Depends(get_db)并不会被FastAPI解析为实际的数据库会话,而是直接把Depends对象赋值给了db变量,自然调用add方法会报错。
另外你代码里的db.session.add(curr_metric)也是错误的——get_db返回的本身就是SQLAlchemy的Session实例,直接调用db.add()即可,不需要再取session属性。
修复方案
下面提供两种可行的修复方式:
方案一:手动创建数据库会话(最简单直接)
在中间件内部直接调用get_db生成器获取会话,处理完成后确保关闭:
@app.middleware("http") async def log_requests(request: Request, call_next): # 手动获取数据库会话 db_generator = get_db() db = next(db_generator) try: response = await call_next(request) # 写入指标数据 curr_metric = models.Metric(rqid=request_id, name="request_duration", duration_ms=total_time_ms) db.add(curr_metric) db.commit() return response finally: # 确保会话关闭 db_generator.close()
方案二:通过FastAPI依赖解析器手动解析依赖
如果需要复用全局的依赖覆盖逻辑,可以用FastAPI内置的依赖解析工具来获取会话:
from fastapi.dependencies.utils import resolve_dependencies @app.middleware("http") async def log_requests(request: Request, call_next): # 解析get_db依赖 resolved_deps = await resolve_dependencies( request=request, dependencies=[Depends(get_db)], dependency_overrides=request.app.dependency_overrides ) db = resolved_deps[0] try: response = await call_next(request) curr_metric = models.Metric(rqid=request_id, name="request_duration", duration_ms=total_time_ms) db.add(curr_metric) db.commit() return response finally: db.close()
额外注意点
- 全局的
app = FastAPI(dependencies=[Depends(get_db)])只会给路由处理函数注入数据库会话,不会作用于中间件,所以中间件里无法直接拿到这个全局注入的会话。 - 无论用哪种方案,都要确保数据库会话最终被关闭,避免连接泄漏。
内容的提问来源于stack exchange,提问作者mascai
相关产品推荐
相关产品推荐

