我在使用 peewee-async 查询 MySQL 时遇到问题(它又使用 aiomysql)
这是我的代码(我认为它与 peewee-async 文档中的示例几乎相同):
import asyncio
import peewee
import peewee_async
database = peewee_async.MySQLDatabase(None)
class BaseModel(peewee.Model):
id = peewee.IntegerField(primary_key=True)
class Meta:
database = database
class User(BaseModel):
name = peewee.CharField(unique=True)
password = peewee.CharField()
role = peewee.CharField()
def get_db(config, loop=None):
database.init(config['database'], user=config['user'], password=config['password'],
host=config['host'], port=config['port'])
objects = peewee_async.Manager(database, loop=loop)
objects.allow_sync = False
return objects
async def print_users(db):
users = await db.execute(User.select())
for user in users:
print(user.id, user.name)
if __name__ == '__main__':
conf = {
'database': 'db',
'user': 'user',
'password': 'secret',
'host': 'localhost',
'port': 3306
}
loop = asyncio.get_event_loop()
db = get_db(conf, loop=loop)
loop.run_until_complete(print_users(db))
现在,当我执行它时,它会查询并打印用户(在我的例子中为 1 个用户)。但随后,它抛出异常:
(env)user@Private-006:~/project$ python tst.py
1 test
Exception ignored in: <bound method Connection.__del__ of <aiomysql.connection.Connection object at 0x7f37ce016978>>
Traceback (most recent call last):
File "/home/user/project/env/lib/python3.5/site-packages/aiomysql/connection.py", line 802, in __del__
File "/home/user/project/env/lib/python3.5/site-packages/aiomysql/connection.py", line 269, in close
File "/usr/lib/python3.5/asyncio/selector_events.py", line 566, in close
File "/usr/lib/python3.5/asyncio/base_events.py", line 497, in call_soon
File "/usr/lib/python3.5/asyncio/base_events.py", line 506, in _call_soon
File "/usr/lib/python3.5/asyncio/base_events.py", line 334, in _check_closed
RuntimeError: Event loop is closed
如有任何帮助,我们将不胜感激。
好的。看来最后添加
loop.run_until_complete(db.close())
有帮助。
让我们暂时将此视为答案,直到有人解释为什么我们应该显式关闭管理器,以及为什么 peewee-async 文档中没有提到这一点。
我遇到了同样的问题。有两种解决方案适合我,代码如下:
首先调用数据库的close_async方法:
await database.close_async()
第二个,
await objects.close()
阅读源码,你会发现objects.close()调用了database.close_async()。