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

context-managed resource on module level

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

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

这是基本布局:

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

现在我想避免每条路线连接。我可以想到外面的一个对象,在路由中我要么访问 conn 属性 要么等待创建(并存储回来)然后只使用 [=17= 上的 with ]方法。

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 context-manager 获取连接:

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

如果池中已存在连接,则它们将为 re-used。