使用Pytest+Moto测试DynamoDB时报list indices类型错误如何解决?
错误触发原因
- 建表参数不符合DynamoDB规范:DynamoDB创建表时,
AttributeDefinitions仅需要声明主键(分区键、排序键)涉及的属性,你在KeySchema中指定id为HASH主键,但AttributeDefinitions中完全没有id的定义,反而额外声明了frequency、time_period、destinations三个非主键属性,直接导致建表失败。 - 属性类型声明与实际写入值不匹配:你在
AttributeDefinitions中将destinations的类型定义为M(Map字典类型),但实际写入的alarm_configs中destinations是List列表类型,类型不匹配会导致写入/读取时解析错误。 - boto3接口用法混淆:你通过
boto3.resource('dynamodb')获取的是资源对象,该对象没有直接的put_item方法,你调用该方法返回的错误结构后续被当作字典用字符串键索引,就会触发list indices must be integers or slices, not str报错。
修复方案
- 修正建表参数,仅保留主键相关的属性定义,删除非主键属性的声明
- 统一使用boto3资源对象的Table接口操作DynamoDB,无需手动处理类型格式化
- 调整代码逻辑,确保建表完成后再执行数据写入操作
修复后的代码示例:
import boto3 from moto import mock_dynamodb @mock_dynamodb def test_save_alarm_configs_in_db(apigw_event): repo = DynamoDBRepository() # 获取dynamodb资源对象 dynamodb = boto3.resource('dynamodb', region_name='us-east-1') # 修正建表参数,AttributeDefinitions仅保留主键id的定义 table = dynamodb.create_table( AttributeDefinitions=[ { 'AttributeName': 'id', 'AttributeType': 'S' } ], TableName='alarm_configs', KeySchema=[ { 'AttributeName': "id", 'KeyType': "HASH" } ], # 增加预置吞吐量配置(moto要求必填) ProvisionedThroughput={ 'ReadCapacityUnits': 1, 'WriteCapacityUnits': 1 } ) # 等待表创建完成 table.wait_until_exists() alarm_configs = { "id": "123", "frequency": 2, "time_period": "hour", "destinations": [ {"type": "SNS", "properties": [{"topics": ["email_topic"]}] } ] } # 通过Table对象写入数据,支持直接传入Python字典 put_response = table.put_item(Item=alarm_configs) print("Put response:") print(put_response) expected_item = repo.get_alarm_configs_by_id("123") print(expected_item)
内容的提问来源于stack exchange,提问作者Adelin
相关产品推荐
相关产品推荐

