asyncio 不正确地警告流对象被垃圾回收;显式调用"stream.close()"



我使用python3.8内置的asyncio包和安装的aiomysql包来实现异步MySQL查询执行。尽管我已经正确关闭了所有打开的光标和连接,但一条错误消息仍会继续出现在我的控制台上,如下所示。

An open stream object is being garbage collected; call "stream.close()" explicitly.

代码摘要如下。。。

#db.py
import asyncio
class AsyncMysqlSession:
def __init__(self, loop, db_settings=DEFAULTDB):
self.db_settings = db_settings
self.loop = loop
async def __aenter__(self):
self.conn = await aiomysql.connect(host=self.db_settings['HOST'],
port=self.db_settings['PORT'],
user=self.db_settings['USER'],
password=self.db_settings['PASSWORD'],
db=self.db_settings['NAME'],
loop=self.loop)
self.cursor = await self.conn.cursor(aiomysql.cursors.DictCursor)
return self
async def __aexit__(self, exception, value, traceback):
await self.cursor.close()
self.conn.close()
async def query(self, sql, *args):
await self.cursor.execute(sql, values)
await self.conn.commit()
rows = await self.cursor.fetchall()
return list(rows)

async def aiomysql_query(sql, *args):
"""
Mysql asynchronous connection wrapper
"""
loop = asyncio.get_event_loop()
async with AsyncMysqlSession(loop) as mysql:
db_result = await mysql.query(sql, *args)
return db_result

aiomysql_query被导入到另一个文件中

#views.py
import asyncio
.....

async def main():
.....
.....

await aiomysql_query(sql1, *args1)
await aiomysql_query(sql2, *args2)
.....
asyncio.run(main())
....

我是在这里做错了什么(?(,还是错误信息显示不正确?。任何解决这一问题的线索都将不胜感激。。。TIA!!

除了@VPfB上面建议的await conn.wait_closed()之外,您似乎刚刚忘记关闭事件循环。

手动使用较低级别的方法调用(如asyncio.get_event_loop()(时,必须关闭事件循环。具体来说,必须调用self.loop.close()

#db.py
import asyncio
class AsyncMysqlSession:
def __init__(self, loop, db_settings=DEFAULTDB):
self.db_settings = db_settings
self.loop = loop
async def __aenter__(self):
self.conn = await aiomysql.connect(host=self.db_settings['HOST'],
port=self.db_settings['PORT'],
user=self.db_settings['USER'],
password=self.db_settings['PASSWORD'],
db=self.db_settings['NAME'],
loop=self.loop)
self.cursor = await self.conn.cursor(aiomysql.cursors.DictCursor)
return self
async def __aexit__(self, exception, value, traceback):
await self.cursor.close()
self.conn.close()
self.loop.close()
async def query(self, sql, *args):
await self.cursor.execute(sql, values)
await self.conn.commit()
rows = await self.cursor.fetchall()
return list(rows)

async def aiomysql_query(sql, *args):
"""
Mysql asynchronous connection wrapper
"""
loop = asyncio.get_event_loop()
async with AsyncMysqlSession(loop) as mysql:
db_result = await mysql.query(sql, *args)
return db_result

参考文献

https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.shutdown_asyncgens

https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.get_event_loop

最新更新