简体   繁体   中英

Only update the value given and ignore other values in dynamodb

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"
        )

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"
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM