Putting/Updating item in DynamoDB fails for the UpdateExpression syntax
<p>I've created a DynamoDB table, and in my Python code, I have the resource initialised as follows:</p>

<pre><code>self.dynamodb = self.session.resource('dynamodb').Table('aws-ci')
</code></pre>

<p>The table has just one index/key, with the name <code>environment</code>. I am trying to <code>PUT</code> into it, an object as follows:</p>

<pre><code>{
  "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"
  }
}
</code></pre>

<p>where, <code>X</code> and <code>Y-Z</code> are the names of micro-services. My insertion code is as follows:</p>

<pre><code>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
</code></pre>

<p>Previously, instead of <code>{0}.current_status</code>, I had <code>{0}.status</code>, but that raised the following error:</p>

<blockquote>
  <p>An error occurred (<code>ValidationException</code>) when calling the
  <code>UpdateItem</code> operation: Invalid <code>UpdateExpression</code>: Attribute name is
  a reserved keyword; reserved keyword: <code>status</code></p>
</blockquote>

<p>Anyway, I changed that attribute name name to <code>current_status</code> and tried the insertion again, only this time I am receiving:</p>

<blockquote>
  <p>An error occurred (<code>ValidationException</code>) when calling the
  <code>UpdateItem</code> operation: The document path provided in the update
  expression is invalid for update</p>
</blockquote>

<p>when trying to set attributes for service <strong>X</strong>, and the following when trying for <strong>Y-Z</strong>:</p>

<blockquote>
  <p>An error occurred (<code>ValidationException</code>) when calling the
  <code>UpdateItem</code> operation: Invalid <code>UpdateExpression</code>: Syntax error;
  token: "-", near: "Y-Z"</p>
</blockquote>

<p>I'm currently unable to understand how the <code>update_item</code> call should work.</p>

<p>Have you tried this?
<a href="http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ExpressionPlaceholders.html#ExpressionAttributeNames" rel="nofollow">http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ExpressionPlaceholders.html#ExpressionAttributeNames</a></p>

<pre><code>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"
)
</code></pre>

python amazon-web-services amazon-dynamodb boto boto3