首页 > 其他分享 >Fastapi中dependency的生命周期

Fastapi中dependency的生命周期

时间:2023-12-01 11:34:46浏览次数:40  
标签:生命周期 get Fastapi db dependency Depends 调用 user 连接

https://bobobo80.com/2021/fastapizhong-dependencyde-sheng-ming-zhou-qi.html

发现问题
最近使用fastapi时,出现了一个alchemysql数据库连接池的错误。超过了默认的连接池限制。按理说自己的服务只有一个人在用,应该不会出现这种问题。

sqlalchemy.exc.TimeoutError: QueuePool limit of size 5 overflow 10 reached, connection timed out, timeout 30.00 (Background on this error at: https://sqlalche.me/e/14/3o7r)
联想到最近的修改是增加了一个文件下载接口,所以查到了原因,是这个接口占用了db连接池。

我最开始是用了fastapi作者在fullstack模板里给的方法写的验证用户登陆状态的dependency。比如下面这个接口,调用了Depends(deps.get_current_active_user),来验证jwt里的用户。

@router.get("/{id}", response_model=schemas.Item)
def read_item(
    *,
    db: Session = Depends(deps.get_db),
    id: int,
    current_user: models.User = Depends(deps.get_current_active_user),
) -> Any:
    """
    Get item by ID.
    """
    pass
get_current_active_user函数在最里层,使用了get_db,这个函数使用了Generator,在调用时返回db连接,在结束时关闭db连接。

def get_db() -> Generator:
    try:
        db = SessionLocal()
        yield db
    finally:
        db.close()
问题就出在了关闭连接这里。那这个get_db举例,当depends调用get_db时,会调用SessionLocal开启一个db连接和事务,然后直到这个请求返回response后才会调用finally后的close。所以如果一个接口内部不光只有db操作,并且在请求最开始调用了get_db开启了db连接,同时后面还有其他一些时间长的操作(比如读文件,请求其他api等),那么这个db连接就会被一直占用着,直到这个请求结束才会关闭。同时这还是一个db事务,如果在最开始有写操作或带锁读操作,还会有长时间的db锁。

我在文档里找到了Depends还有个use_cache用法。默认是True,在同一个请求里,如果Depends调用了同一个函数,在第二次调用时会用cache中的值。所以当一个请求里不同的地方调用了get_db,那么会使用同一个session,不会再创建第二个db连接了,就是在同一个连接和同一个事务里。不过如果把use_cache设置为False,那么在不同的地方调用get_db后,会创建新的db连接和事务。但是,当调用get_db后,并不会立刻执行close,仍然是要在整个请求结束后才执行close。

可能会引起的问题的情况
Depends的这个问题或特性,可能会在Depends中有一些独立的db请求后,没有及时释放db连接。所以这些情况下引起问题: - 在请求最开始,通过Depends获取了db session,比如用户验证。但之后,在这个接口中有时间长的操作,长时间占用db连接。 - 在请求最开始,通过Depends获取了db session,比如用户验证,但用户db在一个不同的库,和后面的业务db不在一起。而后面执行的是业务db的操作,导致用户db连接长时间不用,在最后才释放。

如何解决
因为Depends的这个用法,那么为了及时释放db连接,就不用Generator的方法了。比如可以单独写一个方法,在函数内部就关闭db连接。这样Depends调用这个函数后,也不会导致db连接占用的问题。不过如果user库和业务库在同一个db,那么就没有必要这样了,这样会导致同一个请求连接两次db。

def get_current_active_user_with_single_session(
    token: str = Depends(reusable_oauth2)
) -> models.User:
    # unpackage jwt ...
    try:
        db = SessionLocal()
        user = crud.user.get(db, id=token_data.sub)
    finally:
        db.close()
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    return user

@router.get("/{id}", response_model=schemas.Item)
def read_item(
    *,
    db: Session = Depends(deps.get_db),
    id: int,
    current_user: models.User = Depends(deps.get_current_active_user_with_single_session),
) -> Any:
    pass

标签:生命周期,get,Fastapi,db,dependency,Depends,调用,user,连接
From: https://www.cnblogs.com/bitterteaer/p/17869335.html

相关文章

  • Angular - 生命周期钩子
    Angular会按以下顺序执行钩子方法。可以用它来执行以下类型的操作。钩子方法用途时机ngOnChanges()当Angular设置或重新设置数据绑定的输入属性时响应。该方法接受当前和上一属性值的 SimpleChanges 对象注意,这发生的非常频繁,所以你在这里执行的任何操作都会显著影......
  • Spring Bean 的生命周期,如何被管理的?
    实例化一个Bean,也就是我们通常说的new按照Spring上下文对实例化的Bean进行配置,也就是IOC注入如果这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(StringbeanId)方法,此处传递的是Spring配置文件中Bean的ID如果这个Bean实现了BeanFactoryAware接口,会调用它实现的set......
  • 软件开发生命周期模型——05
    10.极限编程(XP,ExtremeProgramming)定义:XP是一种轻量(敏捷)、高效、低风险、柔性、可预测、科学而且充满乐趣的软件开发方式。由价值观、原则、实践和行为四个部分组成,它们彼此相互依赖、关联,并通过行为贯穿于整个生命周期。与其他方法论的区别:在更短的周期内,更早地提供具体、持续的......
  • Codebeamer—软件全生命周期管理轻量级平台
    产品概述    Codebeamer涵盖了软件研发的生命周期,在一个整合的平台内支持需求管理、测试管理、软件开发过程管理以及项目管理等,同时具有IToperations&DevOps相关的内容,并支持变体管理的功能。对于使用集成的应用程序生命周期管理(ALM)来简化、加快交付的产品开发团队和组织......
  • 什么是 Angular 基于 Constructor Parameter 的 Dependency Injection
    在Angular中,依赖注入(DependencyInjection,DI)是一种设计模式,用于处理如何在不同的代码部分创建和传递依赖对象。在Angular中,我们通常依赖于TypeScript的特性,如构造函数参数(constructorparameters)来执行依赖注入。构造函数参数进行依赖注入是AngularDI系统的一个重要特......
  • 常用的maven dependency依赖
    <dependencies><!--junit--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope><......
  • Java线程生命周期
    操作系统线程生命周期操作系统线程生命状态有5种。初始状态(New)进程正在被创建时的状态。仅为线程对象开辟了一块堆内存,实际上线程在操作系统层面还未创建。就绪状态(Ready)可运行,由于其他进程处于运行状态而暂时停止运行运行状态(Running)该进程此时正占用CPU......
  • Android新手必学:Android的生命周期
    引言在Android开发中,了解和理解Android应用程序的生命周期是非常重要的。Android的生命周期指的是应用程序从创建到销毁的整个过程中,系统调用和管理组件的方法和回调。了解生命周期可以帮助我们更好地管理应用程序的状态和资源,提高应用程序的性能和用户体验。本文将介绍Android应用......
  • PMP项目生命周期的区分
     预测型迭代型增量型敏捷型需求在开发前预先确定需求在交付期间定期细化需求在交付期间频繁细化针对最终可交付成果制定交付计划,然后在项目终了时一次交付最终产品分次交付整体产品的各种子集频繁交付对客户有价值的各种子集(隶属于整体产品)尽量限制变更定期把变更融入项目在交......
  • IBM ELM—系统工程全生命周期管理平台
    产品概述    EngineeringLifecycleManagement是IBM提供的工程全生命周期管理组合工具,帮助企业降低开发成本,应对开发挑战并更快地发展其流程和实践。    随着产品变得更加复杂且数字化,传统的工程开发不再能及时且有效地满足系统工程的复杂度,企业需要更多的团队和......