Conditionally insert an item into a dynamodb table using boto3 Error Attribute name is a reserved keyword

Question:

I am calling this function to put items if an item(state) does not exist, something which I am referring from here : How do I conditionally insert an item into a dynamodb table using boto3 ..

    def put_items_if_doesnt_exist():
      dynamodb = boto3.resource('dynamodb',region_name='us-east-1')
      try:
          table = dynamodb.Table('awssolutions-ssm-hybrid-table')
          response = table.put_item(
          Item={
                  'name':'Execution',
                  'state': 'Locked',
              },
          ConditionExpression='attribute_not_exists(state) AND attribute_not_exists(name)'
          )
      except ClientError as e:
          # Ignore the ConditionalCheckFailedException
          if e.response['Error']['Code'] != 'ConditionalCheckFailedException':
              raise

Problem here is that the state is a reserved word and therefore it fails with the error :

[ERROR] ClientError: An error occurred (ValidationException) when calling the PutItem operation: Invalid ConditionExpression: Attribute name is a reserved keyword; reserved keyword: state

Any suggestions to handle this ?

Asked By: Justin Thomas

||

Answers:

This is where ExpressionAttributeNames come in, they let you use reserved names. You just add a placeholder with the # prefix and in the ExpressionAttributeNames parameter specify its value.

    def put_items_if_doesnt_exist():
      dynamodb = boto3.resource('dynamodb',region_name='us-east-1')
      try:
          table = dynamodb.Table('awssolutions-ssm-hybrid-table')
          response = table.put_item(
          Item={
                  'name':'Execution',
                  'state': 'Locked',
              },
          ConditionExpression='attribute_not_exists(#state) AND attribute_not_exists(#name)',
          ExpressionAttributeNames={"#state": "state", "#name": "name"}
          )
      except ClientError as e:
          # Ignore the ConditionalCheckFailedException
          if e.response['Error']['Code'] != 'ConditionalCheckFailedException':
              raise
Answered By: Maurice