DynamoDB: как предотвратить создание нового элемента в UpdateItem, если элемент не существует
Я запускаю службу AWS Lambda, написанную в Node.js, которая взаимодействует с базой данных DynamoDB. Один из моих методов выполняет обновление (AWS.DynamoDB.DocumentClient(). Update) в DynamoDB для обновления определенного элемента. Моя проблема, однако, в том, что когда я пытаюсь обновить элемент и этот элемент не существует, метод обновления добавляет этот новый элемент в мою таблицу. Это поведение по умолчанию также описано в документации.
Я не хочу, чтобы мой метод создавал новый элемент, если он еще не существует. Я хочу, чтобы это было обновление только в том случае, если запись существует. Если он не существует, он ничего не должен делать. Как мне это достичь? Я ожидаю, что я смогу использовать ConditionalExpression для этого, но попытки, которые я сделал при этом, не были успешными.
Ниже приведен пример текущих параметров, которые я отправляю в функцию обновления. В этом примере я хочу обновить пользователя, у которого есть userId 123, и я хочу установить для этого поля isActive значение "false" для этого пользователя (но я хочу сделать это, только если пользователь 123 существует).
const params = {
TableName: 'users',
Key: {
userId: '123',
},
ExpressionAttributeValues: {
':isActive': 'false'
},
UpdateExpression: 'SET isActive = :isActive',
ReturnValues: 'ALL_NEW',
};
Ответы
Ответ 1
Вы можете использовать ConditionExpression
для этого. Обновление произойдет, если присутствует ключ (то есть userId) и атрибут обновления (то есть isActive) не равен для нового значения, которое вы пытаетесь обновить.
ConditionExpression: "userId = :userIdVal and isActive <> :isActiveVal",
ExpressionAttributeValues: {
':isActive' : 'false',
':userIdVal' : '123'
},
EDIT: -
Это должно сработать. Он должен быть ConditionExpression
(не условное выражение).
var params = {
TableName: 'users',
Key: {
'userId': '123'
},
UpdateExpression: 'SET isActive = :isActiveVal',
ConditionExpression: 'userId = :userIdVal and isActive <> :isActiveVal',
ExpressionAttributeValues: {
':userIdVal' : '123',
':isActiveVal': 'false'
},
ReturnValues: "ALL_NEW"
};
Ответ 2
УсловиеExpression - путь, но вы также можете использовать функцию attribute_exists
:
ConditionExpression: 'attribute_exists(userId)'
Он обновит строку только правильным ключом и выбросит ConditionalCheckFailedException
, если запрошенный ключ не существует.
Цель более очевидна, и вы можете пропустить дополнительную привязку userId.
ref: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html