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