2017-01-26 2 views
10

Я запускаю службу AWS Lambda, написанную в Node.js, которая взаимодействует с базой данных DynamoDB. Один из моих методов выполняет обновление (AWS.DynamoDB.DocumentClient(). Update) в DynamoDB для обновления определенного элемента. Моя проблема, однако, в том, что когда я пытаюсь обновить элемент и этот элемент не существует, метод обновления добавляет этот новый элемент в мою таблицу. Это поведение является по умолчанию, описанным в documentation.DynamoDB: Как предотвратить создание нового элемента в UpdateItem, если элемент не существует

Я не хочу, чтобы мой метод создавал новый элемент, если он еще не существует. Я хочу, чтобы это было обновление только в том случае, если запись существует. Если он не существует, он ничего не должен делать. Как мне это достичь? Я ожидаю, что я смогу использовать ConditionalExpression для этого, но попытки, которые я сделал при этом, не были успешными.

Ниже приведен пример текущих параметров, которые я отправляю в функцию обновления. В этом примере я хочу, чтобы обновить пользователь, который имеет USERID 123 и я хочу, чтобы установить IsActive поля, чтобы «ложное» для этого пользователя (но я только хочу, чтобы это сделать, если пользователь 123 на самом деле существует!)

const params = { 
    TableName: 'users', 
    Key: { 
     userId: '123', 
    }, 
    ExpressionAttributeValues: { 
     ':isActive': 'false' 
    }, 
    UpdateExpression: 'SET isActive = :isActive', 
    ReturnValues: 'ALL_NEW', 
}; 

ответ

12

Вы можете использовать для этого 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" 
}; 
+0

Это один из вариантов, который я действительно пытался. Когда я делаю это, я получаю исключение, ValidationException: значение, предоставленное в ExpressionAttributeValues, не используется в выражениях: keys: {: userIdVal} – Stanley

+0

Похоже, вы не предоставили userIdVal в выражении. Включили ли вы эту часть «userId =: userIdVal» в ConditionExpression? – notionquest

+0

Действительно, у меня есть и проверено правописание и синтаксис. – Stanley

0

ConditionExpression это путь, но вы также можете использовать attribute_exists функцию:

ConditionExpression: 'attribute_exists(userId)' 

Это будет только обновить строку с правильным ключом и бросить ConditionalCheckFailedException если запрошенный ключ Безразлично» t существует.

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

ref: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html

Смежные вопросы