Search code examples
pythonaws-lambdaamazon-dynamodbboto3dynamodb-queries

DynamoDb update using boto3


I am writing a lambda function to update dynamodb item. But the problem is that when I give

 {
  "employee_id": "1",
  "last_name": "jane",
  "first_name": "anderson"
}

It works fine but if you remove the last_name or the first_name the program crashes.I want to make it dynamic like if I provice last_name and employee_id it changes last_name only and same goes with first_name. If I provide both first_name and last_name it changes both. Note: employee_id is used here to fetch the data

 {
  "employee_id": "1",
  "last_name": "jane"
}

It gives an error saying that:

{
  "errorMessage": "'first_name'",
  "errorType": "KeyError",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 10, in lambda_handler\n    first_name= event['first_name']\n"
  ]
}

Lambda function:

import boto3
import json

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Employee')

def lambda_handler(event, context):
    employee_id = event['employee_id']
    last_name= event['last_name']
    first_name= event['first_name']
    update = table.update_item(
        Key={
            'employee_id': employee_id
        },
        ConditionExpression= 'attribute_exists(employee_id)',
        UpdateExpression='SET first_name = :val1, last_name = :val2',
        ExpressionAttributeValues={
            ':val1': last_name,
            ':val2': first_name
        }
    )

Solution

  • There are few possibilities you could deal with the issue. If the first_name is absent you could either skip the filed in DynamoDB, or provide some default/empty value. This is use-case specific and depends on how you want to deal with the missing first_name. You could also throw an error if such situation should not be allowed.

    Either way, there is a check performed if first_name exists in the event.

    Below, is an example of the first option:

    import boto3
    import json
    
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('Employee-wahaj')
    
    def lambda_handler(event, context):
    
        employee_id = event['employee_id']
        last_name = event['last_name']
    
        UpdateExpression = 'SET last_name = :val1'
        ExpressionAttributeValues = {':val1': last_name }
    
    
        if 'first_name' in event:
            
            first_name= event['first_name']
            UpdateExpression = 'SET last_name = :val1, first_name = :val2'
            ExpressionAttributeValues = {
                    ':val1': last_name,
                    ':val2': first_name
                }
    
        update = table.update_item(
            Key={
                'employee_id': employee_id
            },
            ConditionExpression= 'attribute_exists(employee_id)',
            UpdateExpression=UpdateExpression,
            ExpressionAttributeValues=ExpressionAttributeValues
        )
    

    update for first and last names

    Its a basic solution (just few if-else-if), as I don't want to over complicate the example.

    import boto3
    import json
    
    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('Employee-wahaj')
    
    def lambda_handler(event, context):
    
        employee_id = event['employee_id']
    
        if 'first_name' in event and 'last_name' not in event:
    
            first_name = event['first_name']
            UpdateExpression = 'SET first_name = :val1'
            ExpressionAttributeValues = {':val1': first_name }
    
        elif 'last_name' in event and 'first_name' not in event:
    
            last_name = event['last_name']
            UpdateExpression = 'SET last_name = :val1'
            ExpressionAttributeValues = {':val1': last_name}
    
        elif 'first_name' in event and 'last_name' in event:
    
            last_name = event['last_name']
            first_name= event['first_name']
            UpdateExpression = 'SET last_name = :val1, first_name = :val2'
            ExpressionAttributeValues = {
                    ':val1': last_name,
                    ':val2': first_name
                }
    
        else:
            raise ValueError("first_name and last_name not given")
    
    
        update = table.update_item(
            Key={
                'employee_id': employee_id
            },
            ConditionExpression= 'attribute_exists(employee_id)',
            UpdateExpression=UpdateExpression,
            ExpressionAttributeValues=ExpressionAttributeValues
        )