FastAPI(34)- Dependencies with yield 依赖项中使用 yield

简介: FastAPI(34)- Dependencies with yield 依赖项中使用 yield

背景


  • FastAPI 支持在依赖项返回后执行一些额外的步骤
  • 但需要用 yield 代替 return 来达到这一目的

 

版本要求

  • 为了达到上述效果,需要使用 Python 3.7+
  • 或者在 Python 3.6 中安装 backports

pip install async-exit-stack async-generator

 

注意

确保依赖项中只使用一次 yield

 

模拟操作数据库的栗子


Python 操作数据库的大致流程

  1. 连接数据库,创建数据库连接对象
  2. 通过数据库连接对象完成数据库的增删改查
  3. 关闭数据库连接对象

Python 操作 Mysql 教程

 

实际项目中操作数据库

  • 连接数据库通常是一个一次性动作,而且是全局前置操作
  • 不会在不同地方用到数据库,都要重新创建一个数据库连接对象
  • 所以创建数据库连接对象可以通过全局依赖项来完成
  • 不再使用数据库连接对象,就得关闭它,不然数据库连接池的连接数就会只增不减,到最后无法再创建连接对象

 

操作数据库的依赖项

async def get_db():
    # 1、创建数据库连接对象
    db = DBSession()
    try:
        # 2、返回数据库连接对象,注入到路径操作装饰器 / 路径操作函数 / 其他依赖项
        yield db
  # 响应传递后执行 yield 后面的代码
    finally: # 确保后面的代码一定会执行
        # 3、用完之后再关闭
        db.close()


yield 在数据库场景的作用

  • 如果还是用 return,在返回数据库连接对象之后,就无法执行关闭数据库连接对象的操作了,最终导致数据库连接池爆满
  • 这个时候 yield 的作用就出来了,执行完 yield 之后,还会执行 yield 语句后面的代码块
  • 所以返回数据库连接对象,待用完它之后,还能关掉数据库连接对象(通过 finally

 

使用 try 的好处

  • 可以收到使用依赖项时抛出的任何异常
  • 例如,如果某些代码在中间、另一个依赖项或路径操作中的某个点使数据库事务“回滚”或创建任何其他错误,将在依赖项中收到异常
  • 当然,也可以用 except Exception 来捕获指定的异常

 

使用 finally 的好处

无论是否有异常,都会执行 finally 里面的代码,保证能关闭数据库连接对象

 

包含 yield 和 HTTPException 的依赖项


先来看代码

async def test_error(name: str):
    try:
        # 返回 name
        yield name
    finally:
        # finally 抛出异常
        raise HTTPException(status_code=400, detail="姓名错误")
@app.get("/items")
async def read_items(name: str = Depends(test_error)):
    return {"name": name}


请求结果

微信图片_20220515152551.png


finally 虽然抛出了异常,但客户端接收到的响应仍然是 200

 

重点

  • yield 之后抛出异常并不会被异常捕捉程序处理,所以还是返回正常的响应内容
  • 只有在 yield 之前抛出异常,异常捕捉程序才能处理成功,并返回报错响应给客户端
相关文章
FastAPI(33)- Global Dependencies 全局依赖
FastAPI(33)- Global Dependencies 全局依赖
299 0
FastAPI(33)- Global Dependencies 全局依赖
FastAPI(32)- Dependencies in path operation 通过路径操作装饰器的 dependencies 参数声明依赖
FastAPI(32)- Dependencies in path operation 通过路径操作装饰器的 dependencies 参数声明依赖
141 0
FastAPI(32)- Dependencies in path operation 通过路径操作装饰器的 dependencies 参数声明依赖
|
IDE API 开发工具
FastAPI(30)- Classes as Dependencies 类依赖注入 (下)
FastAPI(30)- Classes as Dependencies 类依赖注入 (下)
114 0
FastAPI(30)- Classes as Dependencies 类依赖注入 (下)
|
IDE API 开发工具
FastAPI(30)- Classes as Dependencies 类依赖注入 (上)
FastAPI(30)- Classes as Dependencies 类依赖注入 (上)
219 0
FastAPI(30)- Classes as Dependencies 类依赖注入 (上)
|
NoSQL 关系型数据库 数据库连接
FastAPI(29)- Dependencies 依赖注入的初步使用
FastAPI(29)- Dependencies 依赖注入的初步使用
403 0
FastAPI(29)- Dependencies 依赖注入的初步使用
|
缓存
fastapi 路径依赖项Depends / 装饰器依赖dependencies / 全局依赖 / 带 yield 的依赖
fastapi 路径依赖项Depends / 装饰器依赖dependencies / 全局依赖 / 带 yield 的依赖
412 0
fastapi 路径依赖项Depends / 装饰器依赖dependencies / 全局依赖 / 带 yield 的依赖
|
NoSQL 测试技术 Redis
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(下)
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(下)
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(下)
|
测试技术 数据安全/隐私保护
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(上)
FastAPI(八十四)实战开发《在线课程学习系统》--接口测试(上)
|
存储 测试技术 数据安全/隐私保护
FastAPI(八十三)实战开发《在线课程学习系统》--注册接口单元测试
FastAPI(八十三)实战开发《在线课程学习系统》--注册接口单元测试
FastAPI(八十三)实战开发《在线课程学习系统》--注册接口单元测试
FastAPI(八十二)实战开发《在线课程学习系统》接口开发-- 课程上架下架
FastAPI(八十二)实战开发《在线课程学习系统》接口开发-- 课程上架下架