Cant update Dynamo Db table , getting ValidationEx

2019-07-14 20:46发布

I need to update my dynamo db table by using only partition key. But i got validation exeption. I have created a table with 3 fields.

  1. id (Partition Key)
  2. name (Sort Key)
  3. age

Then i have triyed to update age field using only id.(tryied to modify age 30 to 40) this is my code

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);
    }
});

But i got error like this.

{ [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 }

After getting error, i modified my params variable like this

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

Using this, updation is successfully completed. How to update table using without sort key?

2条回答
ゆ 、 Hurt°
2楼-- · 2019-07-14 21:28

Currently, the DynamoDB update API doesn't have an option to update the item by partition key only. There is no batchUpdateItem API similar to batchWriteItem as well.

So, if the sort key is not available, get all the sort keys of partition key and update each item for the partition and sort key combination.

For the primary key, you must provide all of the attributes. For example, with a simple primary key, you only need to provide a value for the partition key. For a composite primary key, you must provide values for both the partition key and the sort key.

Sample code:-

You may need to change it for your table. The below code uses "Movies" table which has "yearkey" as partition key and "title" as sort key.

The below code updates the "createdate" attribute for the given hash key "2012".

The variable paramsUpdate is formed based on the query operation. Please update it accordingly for your requirement (i.e. table structure). Logic remains same, you just need to change the table name and key values accordingly.

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++;

        }
    }
});
查看更多
淡お忘
3楼-- · 2019-07-14 21:31

In DynamoDB, partition key + sort key is treated as a "composite primary key", which uniquely identifies an item (on the contrary, Dynamo also supports simple primary key, which only contains partition key). So you need both to update an item. This is the reason that you can have two items with the same partition key but different sort key. So if you only provide the partition keys, Dynamo will get confused with which item to update.

For your current table configuration, the only way to update an item given a partition key is to make a query with only partition key to get all the items, and filter out the one with the intended sort key. Then use the combination of partition key and sort key to update this item.

查看更多
登录 后发表回答