不能更新Dynamo Db表,得到ValidationException

不能更新Dynamo Db表,得到ValidationException

问题描述:

我需要通过仅使用分区键来更新我的Dynamo数据库表。但我有验证豁免。 我创建了一个3字段的表格。不能更新Dynamo Db表,得到ValidationException

  1. ID(分区键)
  2. 名(排序关键字)
  3. 年龄

那么我triyed只用ID来更新年龄场(tryied修改年龄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' } 
    }; 

利用这一点,更新用成功完成。如何使用不使用排序键更新表?

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

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

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

示例代码: -

您可能需要改变它的表。下面的代码使用具有“yearkey”作为分区键和“title”作为排序键的“Movies”表。

下面的代码更新给定散列键“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++; 

     } 
    } 
}); 

在DynamoDB,分区键+排序关键字被视为一个“复合主键”,它唯一地标识一个项目(与此相反,发电机还支持简单的主键,它仅包含分区键)。所以你需要同时更新一个项目。这就是您可以拥有两个具有相同分区键但排序键不同的原因。因此,如果您只提供分区密钥,Dynamo会对要更新的项目感到困惑。

对于当前表的配置,更新给予分区键的项目的唯一方法是使查询,只有分区键让所有的物品,并过滤出一个与预期的排序键。然后使用分区键和排序键组合更新这个项目。