【问题标题】:Cant update Dynamo Db table , getting ValidationException无法更新 Dynamodb 表,出现 ValidationException
【发布时间】:2017-04-01 09:00:11
【问题描述】:

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

  1. id(分区键)
  2. 姓名(排序键)
  3. 年龄

然后我尝试仅使用 id 更新年龄字段。(尝试将年龄 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' }
    };

使用它,更新成功完成。如何在没有排序键的情况下更新表?

【问题讨论】:

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


    【解决方案1】:

    在DynamoDB中,partition key + sort key被视为“复合主键”,唯一标识一个item(相反Dynamo也支持简单主键,只包含partition key)。所以你需要同时更新一个项目。这就是您可以拥有两个具有相同分区键但不同排序键的项目的原因。因此,如果您只提供分区键,Dynamo 会混淆要更新的项目。

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

    【讨论】:

      【解决方案2】:

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

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

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

      示例代码:-

      您可能需要为您的桌子更改它。下面的代码使用“电影”表,其中“年键”作为分区键,“标题”作为排序键。

      以下代码更新给定哈希键“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++;
      
              }
          }
      });
      

      【讨论】:

        猜你喜欢
        • 2016-04-08
        • 1970-01-01
        • 1970-01-01
        • 2020-06-13
        • 2022-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多