Как добавить значение для атрибута списка в AWS DynamoDB?

Я использую DynamoDB как K-V db (потому что не так много данных, я думаю, что это хорошо), а часть "V" - это тип списка (около 10 элементов). Там какой-то сеанс добавит к нему новое значение, и я не могу найти способ сделать это в 1 запросе. Я сделал вот что:

item = self.list_table.get_item(**{'k': 'some_key'})
item['v'].append('some_value')
item.partial_save()

Сначала я запрашиваю сервер и сохраняю его после изменения значения. Это не атомно и выглядит уродливо. Есть ли способ сделать это по одному запросу?

Ответ 1

Следующий код должен работать с boto3:

table = get_dynamodb_resource().Table("table_name")
result = table.update_item(
    Key={
        'hash_key': hash_key,
        'range_key': range_key
    },
    UpdateExpression="SET some_attr = list_append(some_attr, :i)",
    ExpressionAttributeValues={
        ':i': [some_value],
    },
    ReturnValues="UPDATED_NEW"
)
if result['ResponseMetadata']['HTTPStatusCode'] == 200 and 'Attributes' in result:
    return result['Attributes']['some_attr']

Метод get_dynamodb_resource здесь:

def get_dynamodb_resource():
    return boto3.resource(
            'dynamodb',
            region_name=os.environ['AWS_DYNAMO_REGION'],
            endpoint_url=os.environ['AWS_DYNAMO_ENDPOINT'],
            aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],
            aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'])

Ответ 2

Вы можете сделать это за 1 запрос, используя UpdateItem API в сочетании с UpdateExpression. Поскольку вы хотите добавить в список, вы должны использовать действие SET с функцией list_append:

SET supports the following functions:

...

  • list_append (operand, operand) - оценивает список с новым элемент добавлен к нему. Вы можете добавить новый элемент в начало или конец списка путем изменения порядка операндов.

Несколько примеров этого можно найти в документации "Изменение элементов и атрибутов с помощью выражений обновления":

  • В следующем примере добавляется новый элемент в список просмотра FiveStar. Имя атрибута выражения #pr является ProductReviews; атрибут значение :r является одноэлементным списком. Если в списке ранее было два элементы, [0] и [1], тогда новый элемент будет [2].

    SET #pr.FiveStar = list_append(#pr.FiveStar, :r)
    
  • Следующий пример добавляет еще один элемент в обзор FiveStar список, но на этот раз элемент будет добавлен в начало список в [0]. Все остальные элементы в списке будут сдвинуты на один.

    SET #pr.FiveStar = list_append(:r, #pr.FiveStar)
    

#pr и :r используют заполнители для имен и значений атрибутов. Более подробную информацию об этом можно найти в документации по именам и значениям атрибутов.