I'm using DynamoDB UpdateItem to update records in my DB. A basic function like this is working for me.
var user = {
userID: '123213',
name: 'John Doe',
age: 12,
type: 'creator'
};
var params = {
TableName:table,
Key:{
"UserID": user.userID
},
UpdateExpression: "set Name = :r, Age=:p, Type=:a",
ExpressionAttributeValues:{
":r":user.name,
":p":user.age,
":a":user.type
},
ReturnValues:"UPDATED_NEW"
};
docClient.update(params, 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, null, 2));
}
});
But...
If I'd like to only update one attribute, the name, like this:
var user = {
userID: '123213',
name: 'John Smith'
};
var params = {
TableName:table,
Key:{
"UserID": user.userID
},
UpdateExpression: "set Name = :r, Age=:p, Type=:a",
ExpressionAttributeValues:{
":r":user.name,
":p":user.age,
":a":user.type
},
ReturnValues:"UPDATED_NEW"
};
It gives me the error that
ExpressionAttributeValues cannot be NULL.
I know that I could dynamically produce the UpdateExpression
String by checking for values in user, like this:
for (var key in user) {
if (user.hasOwnProperty(key)) {
...add to DynamicUpdateExpression..
}
}
but is there a way that I can tell updateItem to ignore the null values and only update the name
?
This is a much simpler answer.
It works when you consider ExpressionAttributeValues an object.
Here's the code:
so first we build up the expression if values are available to be passed, using a simple concatenation technique.
Then we supply the values:
The difficulty is with ExpressionAttributeValues which here, we treat as an object and we can add to the object if we first define it as an object, hence the {}.
Then if the object does not already have the property name it adds it and then adds the value.
The net result is you can have very wide flat records as your records can be extended with variable field names. I.e. this application lists a URL and descriptor. With variable field names, I could add more URLs and descriptors to the same record. There is ultimately a memory limit, yet this type of application, for a few variable fields, would be sufficient for my application.
I was asking the same question...In Java there's the SaveBehavior.UPDATE_SKIP_NULL_ATTRIBUTES but I couldn't find anything like that in aws-sdk for nodejs.
You could use AttributeUpdates instead of UpdateExpression to make a cleaner workaround: