it-swarm.com.ru

Как обновить несколько элементов в таблице DynamoDB одновременно

Я использую DynamoDB, и мне нужно обновить определенный атрибут для нескольких записей. При написании моего требования на псевдо-языке, я хотел бы сделать обновление, которое гласит: «обновить таблицу персон set RelationsStatus = 'замужем”, где personKey IN (key1, key2, key3, ...) »(при условии, что personKey является КЛЮЧ в моей таблице DynamoDB).

Другими словами, я хочу сделать обновление с предложением IN, или я полагаю, что это можно назвать пакетным обновлением. Я нашел this ссылку, которая явно спрашивает, существует ли такая операция, как пакетное обновление, и есть ответ, что ее нет. Однако в нем не упоминаются IN-пункты. документация показывает, что IN-предложения поддерживаются в условных выражениях (одновременно может быть предоставлено 100 значений). Тем не менее, я не уверен, подходит ли такое предложение IN для моей ситуации, потому что мне все еще нужно предоставить обязательный атрибут KEY (который ожидает единственное значение, которое кажется - я могу ошибаться), и я беспокоюсь, что он будет делать полное сканирование таблицы для каждого обновления.

Итак, мой вопрос: как мне выполнить обновление нескольких записей DynamoDB одновременно? На данный момент кажется, что мне придется вызывать оператор обновления для каждого ключа один за другим, и это просто кажется неправильным ...

7
Stanley

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

16
Mark B

Я не знаю, изменилось ли оно с тех пор, как был дан ответ, но сейчас это возможно.

См. Документы: https://docs.aws.Amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html

Я использовал это в JavaScript (отображение новых блоков в массив объектов с требуемой структурой:

let params = {}
let tableName = 'Blocks';

params.RequestItems[tableName] = _.map(newBlocks, block => {
    return {
        PutRequest: {
            Item: {
                'org_id': orgId,
                'block_id': block.block_id,
                'block_text': block.block_text
            },
            ConditionExpression: 'org_id <> :orgId AND block_id <> :block_id',
            ExpressionAttributeValues: {
                ':orgId': orgId,
                ':block_id': block.block_id
            }
        }
    }
})

docClient.batchWrite(params, function(err, data) {
   .... and do stuff with the result

Вы даже можете смешивать puts и deletes

И если вы используете dynogels (вы не можете смешивать их из-за поддержки dynogels, но то, что вы можете сделать, это для обновления (используйте create, потому что за кулисами он передает функцию batchWrite как put)

var item1 = {email: '[email protected]', name: 'Foo 1', age: 10};
var item2 = {email: '[email protected]', name: 'Foo 2', age: 20};
var item3 = {email: '[email protected]', name: 'Foo 3', age: 30};

Account.create([item1, item2, item3], function (err, acccounts) {
  console.log('created 3 accounts in DynamoDB', accounts);
});

Обратите внимание на ограничения DynamoDB ( из документов ):

Операция BatchWriteItem помещает или удаляет несколько элементов в одной или нескольких таблицах. Один вызов BatchWriteItem может записать до 16 МБ данных, которые могут содержать до 25 запросов на установку или удаление. Отдельные записываемые элементы могут достигать 400 КБ.

Если я правильно помню, я думаю, что dynogels разбивает запросы на куски по 25, прежде чем отправлять их, а затем собирает их в одном обещании и возвращает (хотя я не уверен на 100% в этом) - в противном случае функция-обертка была бы хороша просто собрать 

2
Simon Pertersen