0

在我发现的教程中,总是为每个请求打开和关闭连接,例如:

import asyncio
import asyncpg

async def run():
    conn = await asyncpg.connect(user='user', password='password',
                             database='database', host='127.0.0.1')
    values = await conn.fetch('''SELECT * FROM mytable''')
    await conn.close()

loop = asyncio.get_event_loop()
loop.run_until_complete(run())

虽然这适用于单个功能,但 Web 应用程序怎么样?

IE:例如在 Tornado 中,每个 URL 都是一个类,这导致了很多类/方法。

我习惯以阻塞方式打开连接,然后使用包装器进行异步数据库调用,然后关闭连接只是为了优雅地关闭服务器,这种情况下的最佳做法是async/await什么?

4

1 回答 1

3

在没有使用 asyncpg 的情况下,我假设在大多数兼容 asyncio 的包中都有一个异步上下文管理器,可以完全满足您的要求。

就像是:

async with asyncpg.create_pool(**kwargs) as pool:
    async with pool.acquire() as connection:
        async with connection.transaction():
            result = await connection.fetchval(fetch stuff)
            connection.execute(insert stuff with result)

(取自这个问题

检查文档中是否提及上下文管理器或带有async with语句的示例,或者如果没有其他内容,请检查源代码中实现__aenter__,__aexit__方法的类。

编辑1:

上面的例子部分取自我所链接的问题,部分是为了完整性而设计的。但是要解决您对 with 语句正在做什么的评论:

async with asyncpg.create_pool(**kwargs) as pool:
    #in this block pool is created and open
    async with pool.acquire() as connection:
        # in this block connection is acquired and open
        async with connection.transaction():
            # in this block each executed statement is in a transaction
            execute_stuff_with_connection(connection)
        # now we are back up one logical block so the transaction is closed
        do_stuff_without_transaction_but_with_connection(connection)
    # now we are up another block and the connection is closed and returned to the pool
    do_more_stuff_with_pool(pool)
# now we are up another level and the pool is closed/exited/cleaned up
done_doing_async_stuff()

我不确定这是多么好的解释,也许您应该阅读上下文管理器

于 2018-06-02T12:48:17.797 回答