Элемент обновления DynamoDB с условным выражением вместо ключа - PullRequest
0 голосов
/ 05 апреля 2020

Я пытаюсь обновить элемент в DynamodB, добавив условие, не передавая ключ в параметрах. И как только мое состояние станет актуальным. Возможно ли это сделать?

Ниже приведен пример элемента:

{
   "id" : "bcc2f32e-305e-4469-88e2-463724b5c6a9",
   "name" : "toto",
   "email" : "toto@titi.com"
}

Где электронная почта уникальна для элементов.

Я проверил этот код, и он работает:

const name= "updateName";
const params = {
    TableName: MY_TABLE,
    Key: {
        id
    },
    UpdateExpression: 'set #name = :name',
    ExpressionAttributeNames: { '#name': 'name' },
    ExpressionAttributeValues: { ':name': name },
    ReturnValues: "ALL_NEW"
}

dynamoDb.update(params, (error, result) => {
    if (error) {
        res.status(400).json({ error: 'Could not update Item' });
    }
    res.json(result.Attributes);
})

Но я хочу сделать что-то вроде этого (заменить ключ условным выражением):

const params = {
    TableName: MY_TABLE,
    UpdateExpression: 'set #name = :name',
    ConditionExpression: '#email = :email',
    ExpressionAttributeNames: { 
        '#name': 'name',
        '#email': 'email'   
    },
    ExpressionAttributeValues: { 
        ':name': name,
        ':email': email
    },
    ReturnValues: "ALL_NEW"
}
dynamoDb.update(params, (error, result) => {
    if (error) {
        res.status(400).json({ error: 'Could not update User' });
    }
    res.json(result.Attributes);
})

Но этот код не работает.

Любые идеи

Ответы [ 2 ]

2 голосов
/ 05 апреля 2020

Вы не можете обновить элемент в DynamoDB, не используя весь первичный ключ (ключ раздела и ключ сортировки, если имеется). Это потому, что вы должны указать ровно одну запись для обновления. См. Документацию здесь .

Если вы хотите найти элемент, используя поле, которое не является первичным ключом, то вы можете искать с помощью сканирования (потенциально медленного и дорогостоящего) или с помощью Глобальный вторичный индекс (GSI) в этой области. Любой из этих методов требует, чтобы вы выполнили отдельный запрос для поиска соответствующего элемента, а затем использовали его первичный ключ для выполнения обновления.

Похоже, вы хотите выполнить обновление, ожидающее условия. Это не так, как работает DynamoDb; это не может ждать ничего (кроме последовательности, я полагаю, но это несколько другое). Что вы можете сделать, это сделать запрос с условием, и если оно не выполнено (возврат немедленно), повторите запрос позже. Если вы сделаете это, вы должны быть осторожны, чтобы откатить должным образом, или вы можете в конечном итоге сделать очень много запросов очень быстро.

1 голос
/ 05 апреля 2020

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

Кроме того, я не уверен, что вы полностью понимаете, для чего предназначено выражение условия - его нет как предложение 'where' в операторе обновления SQL (т. Е. Update mytable set name = 'test', где email = 'myemail.com'.

Вместо этого логически выражение conditionExpression в обновлении будет быть более похожим на:

update mytable set name = 'test', где key = '12345', но только если количество> 0 - например,

, т.е. вы сообщаете Dynamodb точный ключ запись, которую вы хотите обновить, и, как только она найдет ее, она использует выражение условия, чтобы определить, следует ли продолжить обновление - то есть найдите запись с id = 12345 и измените имя на «test», только из количества больше 0.

Он не использует выражение условия для поиска записей для обновления.

...