От новичка до гуру: Курсы программирования на CyberDuff

Обновлять только указанное значение и игнорировать другие значения в Dynamodb

Привет, я пишу лямбда-функцию, которая обновит DynamoDb с помощью boto3. В этом коде employee_id создается автоматически, но вы должны указать last_name или first_name. Я делаю это с if-else. Если атрибут имеет тенденцию к увеличению, проверки тоже. Я не могу продолжать жить в таком состоянии. Как я могу с этим справиться, какие изменения мне следует внести

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
    )

Код, который я придумал, но не работает

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



Ответы:


1

Вы должны смотреть на сохранение выражения обновления и значений выражения отдельно, а затем передавать полный набор в функцию Lambda.

Это также позволит вам выполнять проверку по каждому параметру (возможно, разбив это на функцию проверки, чтобы избежать чрезмерного размера функции). Таким образом, вы поддерживаете как обязательные, так и необязательные параметры, а затем в конце проверяете, что выражение обновления имеет допустимые параметры.

Возможно, что-то вроде того, что показано ниже?

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
    )

Это может быть дополнительно разбито, чтобы повторно использовать логику с помощью функции, которая может выполнять эти проверки, например, как показано ниже.

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]

Тестовое мероприятие

{
  "new_value": "test",
  "employee_id": "value2",
  "last_name": "value3",
  "first_name": "value4"
}
28.08.2020
  • На самом деле я пытаюсь удалить if condition. Если я добавлю еще один атрибут, например электронную почту, в свой динамодб, и мне придется его обновить, мне нужно будет написать больше проверок, я пытаюсь сделать свой код маленьким и эффективным 28.08.2020
  • если я генерирую следующий оператор динамически в соответствии с ключами в событиях UpdateExpression = 'SET first_name = :val1' Это может сработать, но я не могу этого сделать. Вы можете помочь? Примерно так stackoverflow.com/questions/63283009/ 28.08.2020
  • Вы уверены, что ключи событий верны? Я добавил тестовое событие, которое использовал. Когда я добавляю print('SET ' + seperator.join(update_expression_values)) непосредственно перед тем, как получить результат SET first_name = :val_first_name,last_name = :val_last_name,new_value = :val_new_value 28.08.2020
  • Я прикрепил ссылку на вопрос о stackoverflow. Мне нужно что-то вроде того, что автоматически обновит предоставленные поля. If check будет становиться длиннее с увеличением атрибутов. stackoverflow.com/questions/63283009/ 28.08.2020
  • Я обновил вопрос. Я придумал код, требующий некоторых изменений. employee_id создается автоматически и является первичным ключом. employee_id используется здесь для получения содержимого этого идентификатора. Другой столбец в моей таблице - first_name и last_name. Он динамически обновляется, если указано только first_name, а last_name остается как есть. 28.08.2020
  • Проблема с вашим кодом заключается в том, что он перебирает каждый атрибут индивидуально, но пытается работать так, как если бы все атрибуты были в выражении обновления, но вы используете только один ключ. На мой взгляд, лучше создать оператор обновления и сделать это только один раз (со всеми ключами, которые обновляются). Делая это, вы избегаете использования нескольких кредитов записи, выполняющих обновления одного и того же элемента. 28.08.2020
  • Не могли бы вы объяснить свой код? Мне сложно его понять? 28.08.2020
  • Таким образом, эффективно process_event_key проверяет, существует ли этот ключ в событии, и если он действительно добавляет новое значение в список выражений обновления и новый ключ в словарь expression_attribute_values. Они содержат динамические части запроса на обновление, как только обновление произойдет, оно объединит каждое значение в update_expression_values, чтобы создать строку, подобную SET first_name=:val_first_name,last_name=:val_last_name. expression_attribute_values будет содержать значения. 28.08.2020
  • global update_expression_values global expression_attribute_values Почему они оба находятся в process_event_key и handler 29.08.2020
  • Определение как global означает, что вы можете использовать их в функции процесса, не возвращая их каждый раз. Он просто добавляется к каждому глобалу каждый раз, когда он обрабатывается. 29.08.2020
  • если мы не жестко кодируем значения в process_event_key(event, 'first_name') и хотим взять first_name непосредственно из json, если значение существует, обновите его, в противном случае создайте новый столбец. Мы можем это сделать? 01.09.2020
  • Вы можете сделать это, просто выполнив цикл, но вы должны попытаться хотя бы проверить его действительный столбец :) 02.09.2020
  • Новые материалы

    Основы Spring: Bean-компоненты, контейнер и внедрение зависимостей
    Как лего может помочь нашему пониманию Когда мы начинаем использовать Spring, нам бросают много терминов, и может быть трудно понять, что они все означают. Итак, мы разберем основы и будем..

    Отслеживание состояния с течением времени с дифференцированием снимков
    Время от времени что-то происходит и революционизирует часть моего рабочего процесса разработки. Что-то более забавное вместо типичного утомительного и утомительного процесса разработки. В..

    Я предполагаю, что вы имеете в виду методы обработки категориальных данных.
    Я предполагаю, что вы имеете в виду методы обработки категориальных данных. Пожалуйста, проверьте мой пост Инструментарий специалиста по данным для кодирования категориальных переменных в..

    Игра в прятки с данными
    Игра в прятки с данными Я хотел бы, чтобы вы сделали мне одолжение и ответили на следующие вопросы. Гуглить можно в любое время, здесь никто не забивается. Сколько регионов в Гане? А как..

    «Раскрытие математических рассуждений с помощью Microsoft MathPrompter и моделей больших языков»
    TL;DR: MathPrompter от Microsoft показывает, как использовать математические рассуждения с большими языковыми моделями; 4-этапный процесс для улучшения доверия и рассуждений в математических..

    Раскройте свой потенциал в области разработки мобильных приложений: Абсолютная бесплатная серия
    Глава 6: Работа в сети и выборка данных Глава 1: Введение в React Native Глава 2: Основы React Native Глава 3: Создание пользовательского интерфейса с помощью React Native Глава 4:..

    Все о кейсах: Camel, Snake, Kebab & Pascal
    В программировании вы сталкивались с ними при именовании переменной, класса или функции. Поддержание согласованности типов и стилей случаев делает ваш код более читабельным и облегчает совместную..