Reputation:
Hi I am writing a lambda function that will update the DynamoDb using boto3. In this code employee_id
is auto-generated but you have to provide last_name
or first_name
. I am doing it with if-else
. If the attribute tends to increase so does the checks. I can't keep on going with if condition. How can I tackle this what changes should I make
import boto3
import json
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Employee')
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
)
The code that I came up with but is not working
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']
column = [first_name,last_name]
for i in range(0,len(column):
query = 'SET {} = :val1,:val2'.format(column[i])
response = table.update_item(
Key={
'employee_id': employee_id
},
ConditionExpression= 'attribute_exists(employee_id)',
UpdateExpression = query,
ExpressionAttributeValues={
':val1': first_name,
':val2': last_name
},
ReturnValues="UPDATED_NEW"
)
Upvotes: 4
Views: 1299
Reputation: 35213
You should look at storing the update expression and expression values separately, then passing the complete set into the Lambda function.
This would also allow you to validate against each parameter (perhaps breaking this into a validate function to avoid excessive size of function). This way you support both required and optional parameters, then at the end validate that the update expression has valid parameters.
Perhaps something like the below?
import boto3
import json
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Employee')
def lambda_handler(event, context):
update_expression_values = []
expression_attribute_values = {}
if 'employee_id' in event:
employee_id = event['employee_id']
else:
raise ValueError("employee_id not given")
if 'first_name' in event:
update_expression_values.append('first_name = :val_first_name')
expression_attribute_values[':val_first_name'] = event['first_name']
if 'last_name' in event:
update_expression_values.append('last_name = :val_last_name')
expression_attribute_values[':val_last_name'] = event['last_name']
if len(update_expression_values) < 1:
raise ValueError("first_name and last_name not given")
seperator = ','
update = table.update_item(
Key={
'employee_id': employee_id
},
ConditionExpression= 'attribute_exists(employee_id)',
UpdateExpression='SET ' + seperator.join(update_expression_values),
ExpressionAttributeValues=expression_attribute_values
)
This could be broken down further to reuse the logic through a function that can perform these checks such as the below.
import boto3
import json
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Employee')
update_expression_values = []
expression_attribute_values = {}
def lambda_handler(event, context):
global update_expression_values
global expression_attribute_values
update_expression_values = []
expression_attribute_values = {}
if 'employee_id' in event:
employee_id = event['employee_id']
else:
raise ValueError("employee_id not given")
process_event_key(event, 'first_name')
process_event_key(event, 'last_name')
process_event_key(event, 'new_value')
if len(update_expression_values) < 1:
raise ValueError("first_name and last_name not given")
seperator = ','
update = table.update_item(
Key={
'employee_id': employee_id
},
ConditionExpression= 'attribute_exists(employee_id)',
UpdateExpression='SET ' + seperator.join(update_expression_values),
ExpressionAttributeValues=expression_attribute_values
)
def process_event_key(event, key):
global update_expression_values
global expression_attribute_values
if key in event:
update_expression_values.append(key + ' = :val_' + key)
expression_attribute_values[':val_' + key] = event[key]
Test Event
{
"new_value": "test",
"employee_id": "value2",
"last_name": "value3",
"first_name": "value4"
}
Upvotes: 3