Putting/Updating item in DynamoDB fails for the UpdateExpression syntax
Have you tried this? http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ExpressionPlaceholders.html#ExpressionAttributeNames
set_query = "SET #service_name.current_sha = :current, #service_name.prev_sha = :prev, #service_name.deployed = :is_deployed, #service_name.current_status = :current_status"
updated = self.dynamodb.update_item(
Key = {
'environment': environment
},
UpdateExpression = set_query,
ExpressionAttributeValues = {
':current': service_data.get('current'),
':prev': service_data.get('prev'),
':current_status': service_data.get('status'),
':is_deployed': service_data.get('deployed')
},
ExpressionAttributeNames = {
'#service_name': service_name,
},
ReturnValues = "ALL_NEW"
)
Comments
-
hjpotter92 almost 2 years
I've created a DynamoDB table, and in my Python code, I have the resource initialised as follows:
self.dynamodb = self.session.resource('dynamodb').Table('aws-ci')
The table has just one index/key, with the name
environment
. I am trying toPUT
into it, an object as follows:{ "environment": "beta", "X": { "current_sha": "sha1", "deployed": true, "prev_sha": "sha2", "status": "inactive" }, "Y-Z": { "current_sha": "sha1", "deployed": false, "prev_sha": "sha2", "status": "active" } }
where,
X
andY-Z
are the names of micro-services. My insertion code is as follows:def put_service_data(self, environment, service_name, service_data, status = None): get_previous = self.dynamodb.get_item( Key = { 'environment': environment } ).get(service_name) service_data['prev'] = get_previous and get_previous.get('current_sha') or 'NULL' if status == 'rollback' and get_previous: service_data['current'] = get_previous.get('current_sha') service_data['prev'] = get_previous.get('prev_sha') set_query = "SET {0}.current_sha = :current, {0}.prev_sha = :prev, {0}.deployed = :is_deployed, {0}.current_status = :status".format(service_name) updated = self.dynamodb.update_item( Key = { 'environment': environment }, UpdateExpression = set_query, ExpressionAttributeValues = { ':current': service_data.get('current'), ':prev': service_data.get('prev'), ':status': service_data.get('status'), ':is_deployed': service_data.get('deployed') }, ReturnValues = "ALL_NEW" ) return updated
Previously, instead of
{0}.current_status
, I had{0}.status
, but that raised the following error:An error occurred (
ValidationException
) when calling theUpdateItem
operation: InvalidUpdateExpression
: Attribute name is a reserved keyword; reserved keyword:status
Anyway, I changed that attribute name name to
current_status
and tried the insertion again, only this time I am receiving:An error occurred (
ValidationException
) when calling theUpdateItem
operation: The document path provided in the update expression is invalid for updatewhen trying to set attributes for service X, and the following when trying for Y-Z:
An error occurred (
ValidationException
) when calling theUpdateItem
operation: InvalidUpdateExpression
: Syntax error; token: "-", near: "Y-Z"I'm currently unable to understand how the
update_item
call should work.