Use below codes, I successfully update an item
https://github.com/serverless/examples/blob/master/aws-node-rest-api-with-dynamodb/todos/update.js#L22-L37
const params = {
TableName: process.env.DYNAMODB_TABLE,
Key: {
id: event.pathParameters.id,
},
ExpressionAttributeNames: {
'#todo_text': 'text',
},
ExpressionAttributeValues: {
':text': data.text,
':checked': data.checked,
':updatedAt': timestamp,
},
UpdateExpression: 'SET #todo_text = :text, checked = :checked, updatedAt = :updatedAt',
ReturnValues: 'ALL_NEW',
};
Then I add more attributes:
const params = {
TableName: process.env.DYNAMODB_TABLE,
Key: {
id: event.pathParameters.id,
},
ExpressionAttributeNames: {
'#user_name': 'name',
},
ExpressionAttributeValues: {
':name': data.name,
':email': data.email,
':username': data.username,
':password': data.password,
':checked': data.checked,
':updatedAt': timestamp,
},
UpdateExpression: 'SET #user_name = :name, email = :email, username = :username, password = :password, checked = :checked, updatedAt = :updatedAt',
ReturnValues: 'ALL_NEW',
};
Above codes work fine if I feed all attributes.
$ cat test/user-1.json
{
"name": "Bob",
"email": "bob#example.com",
"username": "bob",
"password": "adfdsfdsf",
"checked": false
}
But if I only want to update part of them, since I needn't update email and password every time, I got error Couldn't fetch the user item.
$ cat test/user-1.json
{
"name": "Bob",
"username": "bob-1",
"checked": false
}
$ curl -X PUT ${url}/${id} --data '#test/user-1.json'
Couldn't fetch the user item.
So how to change the code that I don't have to update all attributes.
The Update API call will not work as the data.email and data.password are undefined.
I would suggest altering the UpdateExpression when you don't need to update those attributes.
I know this is super old, but in case someone else comes across this, I built basically a params factory -- I have a function that returns my params and my ExpressionAttributeValues object and UpdateExpression string only comprise of the variables that pass my validation
Related
I have an update expression like below, which appends a link into the end of a links attribute; but I want to set an extra attribute called twitterLink into NULL in the same UpdateExpression after the append operation is done; can you please help on this?
const params = {
TableName: TABLE_ONE,
Key: {
postId: postId
},
UpdateExpression: "set #links = list_append(if_not_exists(#links, :emptyList), :link",
ExpressionAttributeNames: {
'#links': 'links',
},
ExpressionAttributeValues: {
':link': [link],
':emptyList': []
}
};
I have a table in Dynamo db called Settings the unique keys is email and has an attribute called display_names this is type Map and has the following structure{'123-456': "any name", '789-123': 'another name'}
I'm trying to delete the name at with the attribute '123-456' with the following params
TableName: 'Settings',
Key: {
email: 'user#test.com',
},
UpdateExpression: 'DELETE display_names :p',
ExpressionAttributeValues: '{":p" : {"S": 123-456}}'
};
But when I run the code I get the following error ExpressionAttributeValues contains invalid key: Syntax error; key: \"11\"",
I hope you can help me, thank you in advance!
You can use below UpdateExpression to remove a key from the map.
const keyToDelete = '123-456';
const params = {
TableName: 'Settings',
Key: {
email: 'user#test.com',
},
UpdateExpression: `REMOVE #parent.#key`, // Here. Note: use `` instead of '',
ExpressionAttributeNames: {
"#parent": 'display_names',
"#key": keyToDelete
},
ReturnValues: 'ALL_NEW'
};
I currently have a List attribute in my dynamodb table:
name: "Test User"
recommendations: []
I would like to add new item to the recommendations attribute using the UpdateExpression
const params = {
TableName: 'insiders',
Key:{
"uuid": event.uuid, // WHERE uuid is event.uuid
},
UpdateExpression: "SET #recommendations = :recommendation",
ExpressionAttributeNames: {
"#recommendations": "recommendations",
},
ExpressionAttributeValues: {
":recommendation": [{
"uuid": `ir_${uuidv4()}`,
"recommendation": event.recommendation
}]
},
ReturnValues:"UPDATE_NEW"
};
dynamodb.update(params, function(err, data) { }
I managed to add an object map to recommendations list but when I want to add another one it will replace the object in the recommendation list.
I also tried to use the ADD in UpdateExpression
const params = {
TableName: 'insiders',
Key:{
"uuid": event.uuid,
},
UpdateExpression: "ADD #recommendations :recommendation",
ExpressionAttributeNames: {
"#recommendations": "recommendations",
},
ExpressionAttributeValues: {
":recommendation": [{
"uuid": `ir_${uuidv4()}`,
"recommendation": event.recommendation,
}]
},
ReturnValues:"ALL_NEW"
};
dynamodb.update(params, function(err, data) { }
but Im getting an error
"Invalid UpdateExpression: Incorrect operand type for operator or function; operator: ADD, operand type: LIST",
Okay I already figured out how to add an object to existing map attribute of an item. I used list_append
this will add an object to existing map attribute
const params = {
TableName: 'insiders',
Key:{
"uuid": event.uuid,
},
UpdateExpression: "SET #attrName = list_append(#attrName, :attrValue)",
ExpressionAttributeNames: {
"#attrName": "recommendations",
},
ExpressionAttributeValues: {
":attrValue": [{
"uuid": `ir_${uuidv4()}`,
"recommendation": event.recommendation
}]
},
ReturnValues:"ALL_NEW"
};
i need to update a list on my aws-dynamo database. i have created a table with partition key : email. then iam insert some email id to the table successfully. Now my table like this
email
manaf1#gmail.com
manaf2#gmail.com
manaf3#gmail.com
Then, i tried to update the table with new key "details" and its value is a list. this is my code
var AWS = require("aws-sdk");
var params =
{
TableName: "manaftable1",
Key: { email: "manaf1#gmail.com" },
UpdateExpression: "set #details = list_append (#details, :detailsinput)",
ExpressionAttributeNames: {
"#details": "details"
},
ExpressionAttributeValues: {
":detailsinput":{ "id": "1","mob": "978956" }
}
};
var docClient = new AWS.DynamoDB.DocumentClient();
docClient.update(params, function (err, data) {
if (err)
console.log(JSON.stringify(err, null, 2));
else
console.log(JSON.stringify(data, null, 2));
});
But i got error like this
{
"message": "Invalid UpdateExpression: Incorrect operand type for operator or function; operator or function: list_append, operand type: M",
"code": "ValidationException",
"time": "2016-10-26T11:04:60.756",
"requestId": "SN0NPRHDFHUKBBJHOVI0DFHHRQNSO5AEMVJFFGHF9ASFHUAAJG",
"statusCode": 400,
"retryable": false,
"retryDelay": 0
}
i need response like this after updation
column1 : email
column2 : details
manaf1#gmail.com |
[{"id":"1","mob":"978956"},{"id":"2","mob":"767886"}]
manaf2#gmail.com |
what is the issue related with my code?
As AWS documentation for list_append says:
The new element must be contained in a list, for example to add 2 to a
list, the operand would be [2]
So you need to append an array of objects, not just an object:
var params =
{
TableName: "manaftable1",
Key: { email: "manaf1#gmail.com" },
UpdateExpression: "set #details = list_append (#details, :detailsinput)",
ExpressionAttributeNames: {
"#details": "details"
},
ExpressionAttributeValues: {
":detailsinput": [{ "id": "1","mob": "978956" }]
}
};
If the property does not exist in the object, you can use if_not_exists operand:
var params =
{
TableName: "manaftable1",
Key: { email: "manaf1#gmail.com" },
UpdateExpression: "set if_not_exists(#details, []) set #details = list_append (#details, :detailsinput)",
ExpressionAttributeNames: {
"#details": "details"
},
ExpressionAttributeValues: {
":detailsinput": [{ "id": "1","mob": "978956" }]
}
};
Use list_append() and if_not_exists() together to append to a potentially non-existent list column:
var params = {
TableName: "manaftable1",
Key: { email: "manaf1#gmail.com" },
UpdateExpression: "set #details = list_append(if_not_exists(#details, :empty_list), :detailsinput)",
ExpressionAttributeNames: {
"#details": "details"
},
ExpressionAttributeValues: {
":detailsinput": [{ "id": "1","mob": "978956" }],
":empty_list": []
}
};
When the details attribute is NOT present in the item, the update expression should have just SET without the list_append.
UpdateExpression : "SET #details = :details"
When the details attribute is present in the item and the new update needs to add additional elements in the list, then list_append can be used to add the new element to the list.
UpdateExpression : "set #details = list_append (#details, :details)"
I have created a attribute of type String Set.
When I create the Item and assign an attribute of type SS everything works.
But when I try to update this attribute, the data type changes to a list ("L").
I try this:
qw = new AWS.DynamoDB.DocumentClient();
var params = {
TableName : "myTable",
Key: {
"id": somekey
},
UpdateExpression: "set ssvar= :arrp",
ExpressionAttributeValues: {
":arrp": [ "test", "test2" ]
}
};
qw.update (etc.)
This leads to a change in datatype in dynamodb and in stead of a string set I get a list:
"ssvar": {
"L": [
{
"S": "test"
},
{
"S": "test2"
}
]
}
I have tried all kinds of solutions like below but always my datatype gets changed.
ExpressionAttributeValues: {
":arrp":
"SS": [ "test", "test2" ]
}
How can I update an attribute of type string set?
As of September 2015, there is a createSet function in the DocumentClient that you can use for this.
UPDATE - added example
I've modified your example code to use this function:
qw = new AWS.DynamoDB.DocumentClient();
var params = {
TableName : "myTable",
Key: {
"id": somekey
},
UpdateExpression: "set ssvar= :arrp",
ExpressionAttributeValues: {
":arrp": qw.createSet([ "test", "test2" ])
}
};
qw.update (etc.)
This is an artifact of using the DocumentClient - StringSet is not a JSON type.
The DocumentClient converts a StringSet to the Array native JavaScript type:
https://github.com/aws/aws-sdk-js/blob/master/lib/dynamodb/converter.js#L61. Then the client serializes the native JavaScript Array as a DynamoDB List type: https://github.com/aws/aws-sdk-js/blob/master/lib/dynamodb/converter.js#L12.
If you want to use the StringSet type, you can use the low-level API: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html
An alternative simpler syntax
Upsert Item and Add "A" to set
const documentClient = new AWS.DynamoDB.DocumentClient();
await documentClient.update({
TableName,
Key: { hashKey, sortKey },
AttributeUpdates: {
'userIDs': {
Action: 'ADD',
Value: documentClient.createSet(['A' ])
},
},
}).promise();
Upsert Item and remove "A" from set
await documentClient.update({
TableName,
Key: { hashKey, sortKey },
AttributeUpdates: {
'userIDs': {
Action: 'DELTE',
Value: documentClient.createSet(['A'])
},
},
}).promise();
Update expression docs
documentClient.createSet
documentClient.update