上周我一直在玩AWS,并开始创建Lambda并使用DynamoDB。
我奋斗了好几个小时,想弄清楚为什么我会遇到可怕的The provided key element does not match the schema
错误而且我最终崩溃并投入1
而不是id
。令我震惊的是,Lambda终于奏效了。更多的玩弄,我发现我需要做parseInt(id)
。
有人可以解释原因吗?下面是我用于更新列的简单Lambda。
var AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});
var ddb = new AWS.DynamoDB;
var docClient = new AWS.DynamoDB.DocumentClient();
function updateField(id) {
var params = {
TableName: 'MyTable',
Key: {
'Id': parseInt(id)
},
UpdateExpression: `SET #c = :val`,
ExpressionAttributeNames: {
'#c': 'MyField'
},
ExpressionAttributeValues: {
":val": 1
},
ReturnValues: "UPDATED_NEW"
};
docClient.update(params, function(err, data) {
if (err) {
console.error("Unable to update item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("Updated");
}
});
}
exports.handler = function(event, context) {
ddb.scan({
TableName: 'MyTable',
Limit: 1
}, function(err, data) {
if (err) {
console.log("Error", err);
} else {
var item = data.Items[0];
updateField(item.Id.N);
}
});
};
我正在阅读DynamoDB中的Id
值并使用N
属性。为什么我需要将它解析为int以重用它?这是我在JavaScript中没有理解这么简单的东西,还是DynamoDB正在做一些我不期待的事情?
//Works
Key: {
'Id': parseInt(id)
}
//Does not work even though id came right from the database
Key: {
'Id': id
}
答案 0 :(得分:3)
直接来自AWS.DynamoDB
和AWS.DynamoDB.DocumentClient
的回复之间存在很大差异。简而言之,前者将数字作为字符串返回,而后者将数字作为数字返回。
你正在使用两者,当你可能只是使用一个来避免这样的问题。
var ddb = new AWS.DynamoDB;
var docClient = new AWS.DynamoDB.DocumentClient();
DocumentClient
简化了" pure" DynamoDB调用。来自documentation:
[DocumentClient]注释作为输入参数提供的本机JavaScript类型,以及将带注释的响应数据转换为本机JavaScript类型。
但是,当您在update
使用它时,您没有使用DocumentClient
进行扫描。相反,您直接将AWS.DynamoDB
与ddb.scan()
一起使用。这将返回与DocumentClient不同(并且有点反直觉)格式化结果。特别是,从documentation(在"响应语法"下看),我们看到数字作为字符串返回:
" N":" string"
因此,您可以继续将字符串转换为数字,或者最好交换为使用DynamoDB.DocumentClient
与DynamoDB进行所有常见交互,因为它旨在更好地与Node / Javascript集成。