模块级别的上下文管理资源

问题描述

我正在寻找一种模式,其中有多个功能需要访问上下文管理的资源。

尤其是,我正在使用fastAPI,并希望重新使用aiopg(异步psycopg2)连接。

这是基本布局:

@app.get("/hello")
def hello():
    async with aiopg.connect(...) as conn:
        async with conn.cursor(...):
            return cursor.execute(...)

现在,我想避免每个路由的连接。我可以想到一个外部对象,在路由中,我可以访问conn属性或等待创建(并存储回去),然后仅在with方法上使用cursor()。 / p>

class Pg():
    async def conn(self):
        if not self._conn:
            self._conn = await aiopg.connect(...)
        return self._conn

myPg = Pg()

@app.get("/hello")
def hello():
    conn = await myPg.conn()
    async with conn.cursor(...):
        return cursor.execute(...)

但是,我将失去自动关闭连接的能力。

我想我想念这里确实很明显的东西,希望有人可以指导我如何正确地实现这一点。

谢谢!

解决方法

aiopg提供了一个Pool class,可以管理连接。

只需在模块级别创建一个池实例:

pool = await aiopg.create_pool('<your connection string>')

然后,您可以使用Pool.acquire上下文管理器来建立连接:

async with pool.acquire() as conn:
    ...

如果池中已经存在连接,则将重新使用它们。