在端点中使用以从SQL数据库获取结果时,异步等待不起作用



我是异步等待的新手,并尝试使用它从终点定义的SQL数据库查询方法获取响应

@router.get('/queryDAS')
async def fetch_das_db():
response = await DASDBData().get_all()
logger.info("---ASYNCRONOUS----")
return (json.dumps(response))

但我得到的只是这个错误:response=等待DADBData((.get_all((TypeError:对象列表不能用于"await"表达式

def get_all(self):
"""Get all new data.
@returns:
Return list of dictionaries with team information.
"""

result=[]
statement = """SELECT *
FROM CAE_APPR_ITEM_RESPONSE WHERE ROWNUM <= 500
"""
logger.debug(statement)
cur = self.connection.create_connection().cursor()
cur.execute(statement)
for row in cur:
print(row)
result.append(row)
#return (200,result)
return result

我以为这条消息"---ASYNCHRONOUS——";将首先打印,因为get_all方法将进入event_loop内部,但它没有打印

TL;博士

@router.get('/queryDAS')
async def fetch_das_db():
response = DASDBData().get_all()
logger.info("---ASYNCRONOUS----")
return (json.dumps(await response))

从评论开始,我真的建议您先阅读异步等待是如何工作的。以下是我认为是一个关于异步等待的好教程。

在阅读了教程/说明之后,您将了解response = await DASDBData().get_all()将等待get_all()的结果,然后再继续……其行为与传统的同步代码类似。

现在,如果您删除await关键字,那么您的print语句将在方法完成之前运行,但您也会收到一条关于协程未被等待的警告。这类似于启动一个项目,但永远不会结束它。因此,响应变量将保存协程,某种未来的结果,但这还不存在。

考虑到这一点,您可以在等待的同时返回结果,将最后一条返回语句修改为return (json.dumps(await response))。这将等待未来的结果,并在返回之前将其作为字符串转储。

如果您需要将结果用于其他一些事情,您可以使用import asyncio,然后使用response = await asyncio.gather(response)来获得响应值。这将简单地等待正在运行的协程并返回结果值(即,执行被阻止,直到函数返回一些东西(。然后,你可以随心所欲地得到结果。

旁注:

FastAPI会自动将返回值转换为JSON。除非您使用特殊的格式,否则我建议您只使用return await response(根据您使用的方法,可能需要也可能不需要等待(。

最新更新