问题
This code fails:
import asyncio
from motor import motor_asyncio
_client = motor_asyncio.AsyncIOMotorClient()
_db = _client.db
users = _db.users
async def main():
await users.create_index(
'login',
unique=True
)
if __name__ == '__main__':
#loop = asyncio.get_event_loop()
#loop.run_until_complete(main())
asyncio.run(main())
With this error:
Traceback (most recent call last):
File "/home/sanyash/myrepos/TKP/db.py", line 21, in <module>
asyncio.run(main())
File "/usr/local/lib/python3.7/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/usr/local/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "/home/sanyash/myrepos/TKP/db.py", line 14, in main
unique=True
RuntimeError: Task <Task pending coro=<main() running at /home/sanyash/myrepos/TKP/db.py:14> cb=[_run_until_complete_cb() at /usr/local/lib/python3.7/asyncio/base_events.py:158]> got Future <Future pending cb=[run_on_executor.<locals>._call_check_cancel() at /usr/local/lib/python3.7/motor/frameworks/asyncio/__init__.py:80]> attached to a different loop
When I uncomment two lines with loop and comment asyncio.run it works well. What the matter? I thought asyncio.run is a shortcut for this two lines.
The problem is something in the motor_asyncio implementation, because when I changed main to simple return 42, asyncio.run works well too.
回答1:
What the matter? I thought
asyncio.runis a shortcut for this two lines.
No, it does much more. In particular it creates and sets an new event loop. And this is why you get error: AsyncIOMotorClient() creates some async stuff for default event loop, but another loop created by asyncio.run tries to use it.
If you want to preserve asyncio.run you should move init stuff inside main():
# ...
_client = None
_db = None
users = None
async def main():
global _client, _db, users
_client = motor_asyncio.AsyncIOMotorClient()
_db = _client.db
users = _db.users
# ...
It's a good idea in general to start things when event loop is already set and running instead of doing something at module-level.
来源:https://stackoverflow.com/questions/55425797/asyncio-run-fails-when-loop-run-until-complete-works