AWS Lambda使用SDK v3调用DynamoDB getItem报错求助
解决方案
错误原因分析
- ValidationException:你的DynamoDB表
test_cc_auth的主键id类型,和你传入的{ S: uid }不匹配。比如表的id是数字类型(N),但你传了字符串类型(S),反之亦然。 - TypeError:
@aws-sdk/client-dynamodb是DynamoDB的低级客户端,必须使用DynamoDB原生的带类型标识的数据格式,直接传原始值(id: uid)会导致客户端无法解析类型,从而报错。
修复步骤
步骤1:匹配表主键类型
先到DynamoDB控制台确认test_cc_auth表的主键id类型:
- 如果是字符串类型:确保
uid是字符串(若event.id是数字,需转成字符串:const uid = String(event.id)),保持Key: { id: { S: uid } } - 如果是数字类型:将
uid转成字符串格式(DynamoDB数字类型要求用字符串存储),写法为Key: { id: { N: String(uid) } }
步骤2:更简便的写法(推荐)
使用@aws-sdk/util-dynamodb的marshall工具自动处理类型转换,无需手动指定类型标识:
import { DynamoDBClient, GetItemCommand } from "@aws-sdk/client-dynamodb"; import { marshall, unmarshall } from "@aws-sdk/util-dynamodb"; const dbclient = new DynamoDBClient({region:'us-east-1'}); export const handler = async (event) => { const uid = event.id; console.log("id from test event", uid); const params = { TableName: 'test_cc_auth', Key: marshall({ id: uid }) }; console.log("params object is ", params); let datafound; try { datafound = await dbclient.send(new GetItemCommand(params)); // 将返回的原生格式转成普通JS对象(可选) datafound = datafound.Item ? unmarshall(datafound.Item) : null; console.log("data is : ", datafound); } catch(err) { console.log(err); } const response = { statusCode: 200, body: JSON.stringify(datafound), }; return response; };
类型标识S与不添加的区别
- 带类型标识(如
{ S: "xxx" }):这是DynamoDB的原生数据格式,适用于@aws-sdk/client-dynamodb这类低级客户端。DynamoDB的每个属性都需要明确指定类型(字符串S、数字N、布尔BOOL等),低级客户端要求严格遵循该格式传参,无自动类型转换。 - 不带类型标识(直接传原始值):这种写法仅适用于DynamoDB高级客户端(如
@aws-sdk/lib-dynamodb),或配合@aws-sdk/util-dynamodb的marshall工具。高级客户端会自动识别JS数据类型并转换成DynamoDB原生格式,代码更简洁,贴近普通JS开发习惯。
内容的提问来源于stack exchange,提问作者Sreekanth Dabbeeru
相关产品推荐
相关产品推荐

