AWS Lambda集成DynamoDB创建表报错及后续问题求助
解决AWS Lambda集成DynamoDB的两个常见错误
错误1:ParamValidationError(AttributeDefinitions参数问题)
问题根源
- AttributeDefinitions仅能定义**主键(分区键/排序键)**相关属性,不能包含
alertSent这类非主键字段 - 属性名不符合DynamoDB命名规则:长度需在1-255字符之间,仅允许字母、数字、下划线(_)、点(.)、破折号(-),不能含空格或特殊字符
- 属性名大小写敏感,定义时必须和主键配置完全匹配
修复方法
只在AttributeDefinitions中声明主键属性,删除所有非主键字段的定义。
错误2:ValidationException(BOOL类型不符合枚举值)
问题根源
DynamoDB的主键属性类型仅支持S(字符串)、N(数字)、B(二进制)三种,BOOL是普通属性的合法类型,但绝对不能用于主键定义。你大概率是误将非主键的BOOL类型字段加到了AttributeDefinitions里。
修复方法
- 主键属性仅使用[S/N/B]三种类型
alertSent这类非主键BOOL字段无需在AttributeDefinitions中声明,仅在写入数据(PutItem/UpdateItem)时指定类型即可
修正后的代码示例
假设你的表主键为metricName(分区键,字符串类型)和timestamp(排序键,数字类型),用于记录CloudWatch指标和告警发送状态:
import boto3 dynamodb = boto3.resource('dynamodb') table_name = 'CloudWatchAlertStatus' # 表初始化逻辑(仅需执行一次,后续可注释或删除) def create_table(): try: table = dynamodb.create_table( TableName=table_name, KeySchema=[ {'AttributeName': 'metricName', 'KeyType': 'HASH'}, # 分区键 {'AttributeName': 'timestamp', 'KeyType': 'RANGE'} # 排序键 ], AttributeDefinitions=[ {'AttributeName': 'metricName', 'AttributeType': 'S'}, # 主键类型限定为S/N/B {'AttributeName': 'timestamp', 'AttributeType': 'N'} ], ProvisionedThroughput={'ReadCapacityUnits': 5, 'WriteCapacityUnits': 5} ) table.wait_until_exists() print("Table created successfully") except Exception as e: print(f"Error creating table: {e}") # 写入CloudWatch指标与告警状态 def record_alert_status(metric_name, timestamp, alert_sent): table = dynamodb.Table(table_name) try: response = table.put_item( Item={ 'metricName': metric_name, 'timestamp': timestamp, 'alertSent': {'BOOL': alert_sent}, # 非主键字段在此指定BOOL类型 'metricValue': {'N': '25.6'}, # 示例:数字类型字段 'region': {'S': 'us-east-1'} # 示例:字符串类型字段 } ) print("Data recorded successfully") return response except Exception as e: print(f"Error recording data: {e}") return None # Lambda入口函数 def lambda_handler(event, context): # 示例:从CloudWatch事件中提取指标信息 metric_name = event['detail']['metricName'] timestamp = event['detail']['timestamp'] alert_sent = True # 模拟告警已发送状态 # 首次运行可调用create_table()创建表,后续注释即可 # create_table() record_alert_status(metric_name, timestamp, alert_sent) return {'statusCode': 200, 'body': 'Status recorded'}
额外注意点
- 表创建成功后,请勿重复调用
create_table(),否则会触发报错 - Lambda执行角色需配置DynamoDB的
dynamodb:CreateTable(仅建表时需要)和dynamodb:PutItem权限 - 使用boto3的
resource模式比client更简洁,可自动处理部分类型转换
内容的提问来源于stack exchange,提问作者user2023
相关产品推荐
相关产品推荐

