Pa Narongrit
Pa Narongrit

Reputation: 1

How to update attributes in map DynamoDB

I want to update attributes #name in #info but sometimes #info doesn't exist

table.update_item(
    Key={
        'id': '001'
    },
    UpdateExpression='SET #k = if_not_exists(#k, :i), #k.#ks = :kv',
    ExpressionAttributeNames={
        '#k': 'info',
        '#ks': 'name'
    },
    ExpressionAttributeValues={
        ':i': {},
        ':kv': 'new_name'
    }
)

An error occurred (ValidationException) when calling the UpdateItem operation: Invalid UpdateExpression: Two document paths overlap with each other; must remove or rewrite one of these paths; path one: [info], path two: [info, name]

I want to check if #info exists. If not, create a new #info, if there is, update #name.

Upvotes: 0

Views: 223

Answers (1)

cionzo
cionzo

Reputation: 458

Shortly: try to update the field assuming it exists, in case of failure, check that you got a validation exception due to the non existing field you are trying to update, and create it from the root level.

Otherwise, set the info field as an empty dict at entry creation time.

def udpateItemName(id, val):
    try:
        table.update_item(
            Key={
                'id': id
            },
            UpdateExpression='SET #k.#ks = :kv',
            ExpressionAttributeNames={
                '#k': 'info',
                '#ks': 'name',
            },
            ExpressionAttributeValues={
                ':kv': val
            }
        )
    }
    except botocore.exceptions.ClientError as ce:
        if ce.response['Error']['Code'] != 'ValidationException':
            # some further checks can be made on ['Error']['Message'] here to be sure 
            # that the error is due to non existing path
            raise ce
        table.update_item(
            Key={
                'id': id
            },
            UpdateExpression='SET #k = :kv',
            ExpressionAttributeNames={
                '#k': 'info'
            },
            ExpressionAttributeValues={
                ':kv': {"name": val}
            }
        )
    }   

Upvotes: 0

Related Questions