无法更新Dynamo Db表,获取ValidationException

时间:2016-11-17 17:25:37

标签: node.js amazon-web-services amazon-dynamodb aws-sdk nosql

我需要仅使用分区键来更新我的dynamo db表。但我得到验证的例外。 我创建了一个包含3个字段的表。

  1. id(分区键)
  2. name(排序键)
  3. 年龄
  4. 然后我只使用id来更新age字段。(试图修改年龄30到40)这是我的代码

    var AWS = require("aws-sdk");
    
    AWS.config.update({
        region: "us-east-1",
    
    });
    
    var params = {
        TableName: 'test',
        Key: { id: '100' },
        UpdateExpression: 'set #age = :age ',
        ConditionExpression: '#age = :testAge',
        ExpressionAttributeNames: { '#age': 'age' },
        ExpressionAttributeValues: { ':age': '40', ':testAge': '30' }
    };
    
    var docClient = new AWS.DynamoDB.DocumentClient();
    docClient.update(params, function (err, data) {
        if (err) {
            console.log(err);
        }
        else {
            console.log(data);
        }
    });
    

    但是我得到了这样的错误。

    { [ValidationException: The provided key element does not match the schema]
      message: 'The provided key element does not match the schema',
      code: 'ValidationException',
      time: Thu Nov 17 2016 22:38:01 GMT+0530 (IST),
      requestId: '34PNMFM6CEACQIRHTSV77OI0JRVV4KQNSO5AEMVJF66Q9ASUAAJG',
      statusCode: 400,
      retryable: false,
      retryDelay: 0 }
    

    收到错误后,我修改了我的params变量

     var params = {
            TableName: 'test',
            Key: { id: '100',name: 'manaf' },
            UpdateExpression: 'set #age = :age ',
            ConditionExpression: '#age = :testAge',
            ExpressionAttributeNames: { '#age': 'age' },
            ExpressionAttributeValues: { ':age': '40', ':testAge': '30' }
        };
    

    使用此功能,可以成功完成更新。如何使用不使用排序键更新表?

2 个答案:

答案 0 :(得分:1)

目前,DynamoDB更新API没有按分区键更新项目的选项。没有与batchWriteItem类似的batchUpdateItem API。

因此,如果排序键不可用,请获取分区键的所有排序键,并更新分区和排序组合键的每个项目。

  

对于主键,您必须提供所有属性。对于   例如,使用简单的主键,您只需提供一个值   对于分区键。对于复合主键,您必须提供   分区键和排序键的值。

示例代码: -

您可能需要为表格更改它。下面的代码使用“Movies”表,其中“yearkey”作为分区键,“title”作为排序键。

以下代码更新了给定哈希键“2012”的“createdate”属性。

变量paramsUpdate是基于查询操作形成的。请根据您的要求(即表格结构)进行相应更新。逻辑保持不变,您只需相应地更改表名和键值。

var AWS = require("aws-sdk");
var creds = new AWS.Credentials('akid', 'secret', 'session');

AWS.config.update({
    region : "us-west-2",
    endpoint : "http://localhost:8000",
    credentials : creds
});

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

var hashKey = 2012;

var paramsQuery = {
    TableName : "Movies",
    KeyConditionExpression : 'yearkey = :hkey',
    ExpressionAttributeValues : {
        ':hkey' : hashKey

    }
};

function updateItem(paramsUpdate) {
    console.log("Updating the item...");
    docClient.update(paramsUpdate, function(err, data) {
        if (err) {
            console.error("Unable to update item. Error JSON:", JSON.stringify(
                    err, null, 2));
        } else {
            console.log("UpdateItem succeeded:", JSON.stringify(data));
        }
    });
}

docClient.query(paramsQuery, function(err, data) {
    if (err) {
        console.error("Unable to read item. Error JSON:", JSON.stringify(err,
                null, 2));
    } else {
        console.log(data.Count);
        var itemIndex = 0;
        while (itemIndex < data.Count) {

            console.log('Hashkey to be updated ======>',
                     data.Items[itemIndex].yearkey,
                     ';Title to be updated ========>',
                     data.Items[itemIndex].title);
            var paramsUpdate = {
                TableName : "Movies",
                Key : {
                    "yearkey" : data.Items[itemIndex].yearkey,
                    "title" : data.Items[itemIndex].title
                },
                UpdateExpression : "set #createdate = :createdate",
                ExpressionAttributeNames : {
                    '#createdate' : 'createdate'
                },
                ExpressionAttributeValues : {
                    ':createdate' : '2016-11-17'
                },
                ReturnValues : 'UPDATED_NEW'
            };
            updateItem(paramsUpdate);
            itemIndex++;

        }
    }
});

答案 1 :(得分:1)

在DynamoDB中,分区键+排序键被视为“复合主键”,它唯一地标识项目(相反,Dynamo也支持简单主键,它只包含分区键)。所以你需要更新一个项目。这就是为什么您可以使用相同的分区键但排序键不同的两个项目。因此,如果您只提供分区键,Dynamo将会对要更新的项目感到困惑。

对于当前的表格配置,给定分区键更新项目的唯一方法是使用分区键进行查询以获取所有项目,并过滤输出具有预期排序键的那个。然后使用分区键和排序键的组合来更新此项目。