Python查询DynamoDB遇不存在条目崩溃,异常处理问题咨询
解决DynamoDB查询不存在条目时的KeyError问题
你的判断完全正确——问题出在异常处理的范围上。当你查询不存在的MSISDN时,table.get_item()并不会抛出ClientError,而是返回一个不包含'Item'键的响应字典。这时候你直接访问response['Item']['Name']就会触发KeyError,而这个异常不在你当前的except ClientError捕获范围内,所以程序直接崩溃了。
问题根源
DynamoDB的get_item()接口只有在出现服务端错误(比如权限不足、表不存在等)时才会抛出ClientError。如果只是查询的条目不存在,它会正常返回响应,只是响应里没有'Item'字段。
修复方案
有两种常用的修复方式,推荐第一种(更符合业务逻辑的处理方式):
方式1:先检查响应中是否存在Item
在提取字段前先判断'Item'是否存在,这样能主动处理条目不存在的情况,避免依赖异常捕获:
import boto3 from botocore.exceptions import ClientError dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('PhoneList') # Phone Number # -> Existent: 44790000000 msisdn = 44790000000 # 可以替换为不存在的号码测试 try: response = table.get_item(Key={'MSISDN': msisdn}) # 先判断条目是否存在 if 'Item' not in response: print("Phone number not found") exit(-1) # 条目存在时再提取字段 name = response['Item']['Name'] ID = str(response['Item']['ID']) birth = response['Item']['Birth'] except ClientError as e: print(e.response['Error']['Message']) exit(-1) # 注意:原代码里的print("ID:", id)是错误的,id是Python内置函数,要用你定义的ID变量 print("Phone:", msisdn) print("Name:", name) print("ID:", ID) print("Birth:", birth)
方式2:捕获KeyError异常
如果你更倾向于用异常处理的方式,也可以把KeyError加入捕获范围:
import boto3 from botocore.exceptions import ClientError dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('PhoneList') msisdn = 44790000000 try: response = table.get_item(Key={'MSISDN': msisdn}) name = response['Item']['Name'] ID = str(response['Item']['ID']) birth = response['Item']['Birth'] except ClientError as e: print(e.response['Error']['Message']) exit(-1) except KeyError: print("Phone number not found") exit(-1) print("Phone:", msisdn) print("Name:", name) print("ID:", ID) print("Birth:", birth)
额外提示
原代码里还有一个小问题:print("ID:", id)中的id是Python的内置函数,会覆盖你定义的ID变量,导致输出错误,已经在修复后的代码里修正了。
内容的提问来源于stack exchange,提问作者Andre
相关产品推荐
相关产品推荐

