在Tornado异步流程中用@gen.coroutine和yield调用DynamoDB可行吗?
在Tornado的@gen.coroutine中使用DynamoDB的正确方式
首先明确:Tornado的@gen.coroutine装饰器确实可以和aioboto3配合操作DynamoDB,你的代码无法运行是因为几个具体错误,下面逐一排查并修正:
错误点分析
- 拼写错误:
session.rosource是笔误,正确应为session.resource - 异步操作处理错误:
- aioboto3的
Session不需要用with (yield session)的写法,直接创建资源即可 dynamo_resource.Table()是同步方法,无需加yield,只有query这类实际数据库操作是异步的,需要yield
- aioboto3的
- 依赖缺失:代码中使用了
Key条件表达式,但未导入对应模块,会触发NameError
修正后的代码
from tornado import gen import aioboto3 from boto3.dynamodb.conditions import Key # 补充Key的导入 @gen.coroutine def test(): data = {} session = aioboto3.Session() # 获取DynamoDB资源,异步操作需yield dynamo_resource = yield session.resource('dynamodb', region_name='us-east-1', verify=False) # Table是同步创建的对象,无需yield table = dynamo_resource.Table('sample_table') # query是异步方法,yield获取结果 result = yield table.query( KeyConditionExpression=Key('user_id').eq('user001') ) for index, item in enumerate(result['Items']): data[f"item{index}"] = item print(data)
额外说明
Tornado的@gen.coroutine会将异步函数转换为基于yield的协程,aioboto3的异步方法返回标准asyncio Future对象,Tornado能自动处理这类对象。如果需要用异步上下文管理器,在@gen.coroutine中可以通过yield gen.coroutine(lambda: async with ...)()实现,但本场景不需要。
另外,Tornado 5.0及以上版本官方更推荐直接用async/await语法(你已验证可行),@gen.coroutine更多用于兼容旧代码。
内容的提问来源于stack exchange,提问作者user20035511
相关产品推荐
相关产品推荐

