You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用函数触发RuntimeError:关闭连接池后无法获取连接(未手动关闭池)

问题描述

调用函数时触发错误:

RuntimeError: Cannot acquire connection after closing pool

但代码中并未主动关闭连接池。

相关代码

from aiomysql import create_pool, Cursor
import asyncio
from env import DATABASE, HOST, PORT, USER, PASSWORD


class Table:
    def __init__(self) -> None:
        l = asyncio.get_event_loop()
        self.pool = l.run_until_complete(create_pool(
            host=HOST,
            port=PORT,
            user=USER,
            password=PASSWORD,
            db=DATABASE,
            cursorclass=Cursor,
            autocommit=True,
            loop = asyncio.get_event_loop(),
            maxsize=15
        ))


    async def f(self):
        async with self.pool as pool:
            async with pool.acquire() as conn:
                async with conn.cursor() as cursor:
                    QUERY = f"""SELECT 1;"""
                    await cursor.execute(QUERY, (user_id))
                    return (await cursor.fetchone())[0]

报错回溯

File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 415, in _process_polling_updates
    for responses in itertools.chain.from_iterable(await self.process_updates(updates, fast)):
                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 235, in process_updates
    return await asyncio.gather(*tasks)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiogram\dispatcher\handler.py", line 117, in notify
    response = await handler_obj.handler(*args, **partial_data)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 256, in process_update
    return await self.message_handlers.notify(update.message)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiogram\dispatcher\handler.py", line 117, in notify
    response = await handler_obj.handler(*args, **partial_data)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\User\Desktop\main.py", line 137, in start
    test = await table.f()
           ^^^^^^^^^^^^^^^
  File "c:\Users\User\Desktop\main.py", line 43, in f
    async with pool.acquire() as conn:
  File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiomysql\utils.py", line 134, in __aenter__
    self._conn = await self._coro
                 ^^^^^^^^^^^^^^^^
  File "C:\Users\User\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiomysql\pool.py", line 139, in _acquire
    raise RuntimeError("Cannot acquire connection after closing pool")
RuntimeError: Cannot acquire connection after closing pool
问题原因

问题出在f方法里的async with self.pool as pool这行代码。aiomysql的连接池对象在使用async with上下文管理器时,退出上下文会自动调用close()方法关闭连接池。这意味着第一次调用f()方法后,连接池就被关闭了,后续再调用f()尝试获取连接时,就会触发报错。

修复方案

去掉多余的async with self.pool as pool,直接使用self.pool获取连接即可。同时注意代码中user_id变量未定义、单元素元组格式错误的问题,一并修正。

修正后的代码:

from aiomysql import create_pool, Cursor
import asyncio
from env import DATABASE, HOST, PORT, USER, PASSWORD


class Table:
    def __init__(self) -> None:
        l = asyncio.get_event_loop()
        self.pool = l.run_until_complete(create_pool(
            host=HOST,
            port=PORT,
            user=USER,
            password=PASSWORD,
            db=DATABASE,
            cursorclass=Cursor,
            autocommit=True,
            loop = asyncio.get_event_loop(),
            maxsize=15
        ))


    async def f(self, user_id):  # 补充user_id参数
        async with self.pool.acquire() as conn:
            async with conn.cursor() as cursor:
                QUERY = """SELECT 1;"""  # 无需f-string,无变量替换需求
                await cursor.execute(QUERY, (user_id,))  # 单元素元组需加逗号,避免被识别为单个值
                result = await cursor.fetchone()
                return result[0] if result else None

另外可以优化连接池初始化方式,避免在__init__中阻塞事件循环:

class Table:
    def __init__(self) -> None:
        self.pool = None

    async def init_pool(self):
        self.pool = await create_pool(
            host=HOST,
            port=PORT,
            user=USER,
            password=PASSWORD,
            db=DATABASE,
            cursorclass=Cursor,
            autocommit=True,
            loop=asyncio.get_event_loop(),
            maxsize=15
        )

# 使用时先初始化连接池
table = Table()
await table.init_pool()

内容的提问来源于stack exchange,提问作者izen02

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 11:40:09