4

I'm using NodeJS's aws-sdk and am trying to do an update such that if the item doesn't exist it will throw an error. I'm using the Expression API instead of the legacy one. Here is my contrived example that isn't working for me.

client.update({
    TableName: 'User', 
    Key: {'_id': '10'}, 
    UpdateExpression: 'SET username = :user, password = :pword', 
    ConditionalExpression: 'attribute_exists(#idKey) AND #idKey = :idVal', 
    ExpressionAttributeNames: {
        '#idKey': '_id'
    }, 
    ExpressionAttributeValues: {
        ':idVal': '10', 
        ':user': 'user10', 
        ':pword': 'password10'
    }}, function(err, data){
        if(err) console.log(err); 
        else console.log(data);
});

ValidationException: Value provided in ExpressionAttributeNames unused in expressions: keys: {#idKey}

I've tried various other ConditionalExpressions both using attribute names and inserting the actual value into the expression. I'm beginning to think this is a bug. Using the legacy Expected->Exists with the legacy AttributeUpdate works but I am unable to demonstrate this feature with Expressions.

Nikordaris
  • 2,297
  • 5
  • 20
  • 30
  • I realize this is an old question, but did you ever find an answer to this? I'm experiencing the exact same. – Stanley Jan 26 '17 at 12:21
  • Nope never resolved it. I ended up moving on to a different database for unrelated reasons but am looking to use it again for a new protect. I'm a little disappointed that this issue is still lingering unresolved. I'll post an update if I can resolve it on my new project. – Nikordaris Jan 27 '17 at 13:57
  • I posted a similar question and was able to get to a resolution. See http://stackoverflow.com/questions/41873769/dynamodb-how-to-prevent-creating-a-new-item-in-updateitem-if-the-item-does-not/41874889?noredirect=1#comment70932075_41874889 – Stanley Jan 30 '17 at 05:06
  • Thanks, I'll have to go back and test whether I was using ConditonExpression in my code or if I had a typo when posting this question – Nikordaris Jan 31 '17 at 08:33

1 Answers1

1

You are already narrowing down to the specific item where _id=10 with the Key parameter of your UpdateItemRequest. If an item does not exist, you cannot condition the UpdateItem call on a specific value of a key. Therefore, only the attribute_exists(#idKey) in the ConditionExpression is necessary.

The following code elicits the behavior you desire (I had to change table name to Images and primary key to Id to match the contents of the DynamoDB Local Shell tutorial.

var params = {
    TableName: 'Image',
    Key: { // The primary key of the item (a map of attribute name to AttributeValue)
        '_id': 'dynamodb.png'
    },
    UpdateExpression: 'SET username = :user, password = :pword',
    ConditionExpression: 'attribute_exists(#id)',
    ExpressionAttributeValues: {
        ':user': 'user10', 
        ':pword': 'password10'
    },
    ExpressionAttributeNames: {
        '#id': '_id'
    },
    ReturnValues: 'ALL_NEW'
};
docClient.update(params, function(err, data) {
    if (err) ppJson(err); // an error occurred
    else ppJson(data); // successful response
});

As a reminder, please do not post any real password data here :)

Alexander Patrikalakis
  • 5,054
  • 1
  • 30
  • 48
  • 1
    Thanks for your answer. My intention is to prevent a new entity from being created if it doesn't exist. Shouldn't the ConditionExpression be attribute_exists()? Also, since my original error was with ExpressionAttributeNames this answer should use it as well to prove it works for the original scenario. I think my ultimate problem was the typo of ConditionExpression but I haven't confirmed it yet. – Nikordaris Feb 06 '17 at 09:01
  • You are correct, I will update my answer. I will add expr attr names as well. If it works, please upvote! – Alexander Patrikalakis Feb 06 '17 at 09:03
  • Ok, I've confirmed this works. Thanks for the tip about removing they #idKey = :idVal from the ConditionExpression. I think my main problem was the typo of ConditionalExpression instead of ConditionExpression. The error I was seeing was because the ExpressionAttributeNames were only used in the ConditionExpression which wasn't getting evaluated because of the typo. Thus the unused attribute name error. – Nikordaris Feb 07 '17 at 15:34