[英]Asyncio python - TypeError: A Future, a coroutine or an awaitable is required
One of the async function returns the async generator object.异步函数之一返回异步生成器对象。 I added loop.run_until_complete(func()), but still, it throws the error as "TypeError: A Future, a coroutine or an awaitable is required".
我添加了 loop.run_until_complete(func()),但它仍然抛出错误“TypeError: A Future, a coroutine or an awaitable is required”。 Below is the code.
下面是代码。 I'm trying to fetch the records from Neo4j asynchronously.
我正在尝试从 Neo4j 异步获取记录。 I got the async "Neo4j class from a GitHub. I'm new to this async concept.
我从 GitHub 获得了异步“Neo4j 类。我是这个异步概念的新手。
from concurrent import futures
import neo4j
from neo4j import GraphDatabase, basic_auth
import time
import traceback
import asyncio
RETRY_WAITS = [0, 1, 4] # How long to wait after each successive failure.
class Neo4j:
"""Neo4j database API."""
def __init__(self, config, loop):
self.config = config
self.loop = loop
self.executor = futures.ThreadPoolExecutor(max_workers=30)
for retry_wait in RETRY_WAITS:
try:
self.init_driver()
break
except:
if retry_wait == RETRY_WAITS[-1]:
raise
else:
print('WARNING: retrying to Init DB; err:')
traceback.print_exc()
time.sleep(retry_wait) # wait for 0, 1, 3... seconds.
def init_driver(self):
auth = basic_auth(self.config['user'], self.config['pass'])
self.driver = GraphDatabase.driver(self.config['url'], auth=auth)
async def afetch_start(self, query):
session = self.driver.session(access_mode=neo4j.READ_ACCESS)
def run():
return session.run(query).records()
return session, await self.loop.run_in_executor(self.executor, run)
async def afetch_iterate(self, session, iter):
def iterate():
try:
return next(iter)
except StopIteration:
return None
while True:
res = await self.loop.run_in_executor(self.executor, iterate)
if res is None:
return
else:
yield dict(res)
async def afetch(self, query):
for retry_wait in RETRY_WAITS:
try:
session, iter = await self.afetch_start(query)
break
except (BrokenPipeError, neo4j.exceptions.ServiceUnavailable) as e:
if retry_wait == RETRY_WAITS[-1]:
raise
else:
await asyncio.sleep(retry_wait)
await self.loop.run_in_executor(self.executor, self.init_driver)
async for x in self.afetch_iterate(session, iter):
yield x
await self.loop.run_in_executor(self.executor, session.close)
async def afetch_one(self, query):
async for i in self.afetch(query):
return i
return None
async def aexec(self, query):
async for i in self.afetch(query):
pass
return
config={'url':"bolt://localhost",'user':'neo4j','pass':'pwd'}
loop=asyncio.get_event_loop()
n=Neo4j(config,loop)
loop.run_until_complete(n.afetch("MATCH(p:Person)-[:Acted_in]->(mv:Movies) RETURN p.name as actors"))
loop.close()
--EDIT - 编辑
I have modified the code to work properly.我已经修改了代码以正常工作。 The query returns 218K rows and it takes 5 minutes to extract the complete list and the same async operation in C# completes in just 2 sec.
查询返回 218K 行,提取完整列表需要 5 分钟,而 C# 中的相同异步操作只需 2 秒即可完成。 Looks like the above code still doesnt go in async
看起来上面的代码仍然没有进入异步
It's very hard to tell what exactly happens without reproducible example , but I'll take a guess.如果没有可重现的例子,很难说到底发生了什么,但我会猜测一下。 You probably pass async generator object in a loop, you shouldn't do it.
您可能在循环中传递异步生成器对象,您不应该这样做。 A way to work with async generators is to use
async for
.使用异步生成器的一种方法是使用
async for
。 Here's example:下面是例子:
import asyncio
async def func(): # async generator
yield 1
yield 2
yield 3
async def main():
async for i in func(): # get values from async generator
print(i)
asyncio.run(main()) # can be used instead of loop.run_until_complete(main())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.