Skip to content

Instantly share code, notes, and snippets.

@pgolding
Last active August 22, 2017 15:40
Show Gist options
  • Save pgolding/231f5ce02b7e1fd16a7edc656aa8433e to your computer and use it in GitHub Desktop.
Save pgolding/231f5ce02b7e1fd16a7edc656aa8433e to your computer and use it in GitHub Desktop.
DynamoDB Expression builder for update_item method in Boto3 (Python)

The update_item method in Boto3 requires preparing something like this:

try:
    result = table.update_item(
        Key={
            'id': event['pathParameters']['id']
        },
        ExpressionAttributeNames=attr_names,
        ExpressionAttributeValues=expression_vals,
        UpdateExpression=update_expression,
        ReturnValues='ALL_NEW',
    )
    return respond(None,result)
except Exception as err:
    print(err) # to logs
    return respond(err)

This is for an AWS Lambda function where event['pathParameters']['id'] is the id parameter from the PUT call.

To merely pass in the event['body'] data and prepare for an update, where the assumption is to update any/all of the fields present in the data JSON object, the following is useful:

def buildExpression(data):
    pf = 'prefix'
    timestamp = int(time.time() * 1000)
    data['updatedAt'] = timestamp
    vals = {}
    exp = 'SET '
    attr_names = {}
    for key,value in data.items():
        vals[':{}'.format(key)] = value
        attr_names['#pf_{}'.format(key)] = key
        exp += '#pf_{} = :{},'.format(key, key)
    exp = exp.rstrip(",")
    return vals, exp, attr_names

pf is a useful prefix to label the aliases (in ExpressionAttributeNames) for logging/debugging. It seems safer merely to rename all fields with a #pf prefix in order to avoid any collisions with reserved keywords without having to catch them explicitly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment