为什么我需要从DynamoDB中为parseInt提供数字?

时间:2018-05-18 22:30:52

标签: javascript amazon-dynamodb

上周我一直在玩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
}

1 个答案:

答案 0 :(得分:3)

直接来自AWS.DynamoDBAWS.DynamoDB.DocumentClient的回复之间存在很大差异。简而言之,前者将数字作为字符串返回,而后者将数字作为数字返回。

你正在使用两者,当你可能只是使用一个来避免这样的问题。

var ddb = new AWS.DynamoDB;
var docClient = new AWS.DynamoDB.DocumentClient();

DocumentClient简化了" pure" DynamoDB调用。来自documentation

  

[DocumentClient]注释作为输入参数提供的本机JavaScript类型,以及将带注释的响应数据转换为本机JavaScript类型。

但是,当您在update使用它时,您没有使用DocumentClient进行扫描。相反,您直接将AWS.DynamoDBddb.scan()一起使用。这将返回与DocumentClient不同(并且有点反直觉)格式化结果。特别是,从documentation(在"响应语法"下看),我们看到数字作为字符串返回:

  

" N":" string"

因此,您可以继续将字符串转换为数字,或者最好交换为使用DynamoDB.DocumentClient与DynamoDB进行所有常见交互,因为它旨在更好地与Node / Javascript集成。