如果项目不存在,如何防止在UpdateItem中创建新项目

时间:2017-01-26 12:46:30

标签: amazon-dynamodb

我正在运行用Node.js编写的AWS Lambda服务,该服务与DynamoDB数据库交互。我的一种方法在DynamoDB上执行更新(AWS.DynamoDB.DocumentClient()。update)以更新特定项目。但问题是,当我尝试更新项目并且该项目不存在时,更新方法会将此新项目添加到我的表格中。此行为也是documentation中描述的默认行为。

我不希望我的方法创建一个新项目,如果它尚不存在。我希望这只是在记录存在时才更新。如果它不存在则必须什么也不做。我该如何实现这一目标?我希望我能够使用ConditionalExpression来实现这一目标,但我这样做的尝试并没有成功。

下面给出了发送到更新功能的当前参数的示例。在此示例中,我想更新具有userId 123的用户,并且我想将isActive字段设置为' false'对于这个用户(但我只想在用户123确实存在的情况下这样做!)

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

3 个答案:

答案 0 :(得分:22)

您可以使用ConditionExpression。如果密钥(即userId)存在且更新属性(即isActive)与您尝试更新的新值不等,则会发生更新。

ConditionExpression: "userId = :userIdVal and isActive <> :isActiveVal",
ExpressionAttributeValues: {
    ':isActive' : 'false',
    ':userIdVal' : '123'
},

修改: -

这应该有效。它应该是 ConditionExpression(不是ConditionalExpression)。

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"
};

答案 1 :(得分:15)

ConditionExpression是可行的方法,但您也可以使用attribute_exists函数:

ConditionExpression: 'attribute_exists(userId)'

它只会使用正确的密钥更新该行,如果请求的密钥不存在,则抛出ConditionalCheckFailedException

目标更明显,您可以跳过额外的userId绑定。

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

答案 2 :(得分:0)

我使用attribute_exists遇到了某种类似的问题,唯一的区别是,我需要从表中查询并仅获取具有所需属性的记录。使用ConditionExpression对我不起作用。想在这里共享它,以防万一有人需要。

在这里,如果subscriberKey等于给定的参数,并且记录中的attribute_exists(移动电话号码),则返回true,否则返回false

var params = {
    TableName : table_name,
    IndexName: "subsciberKey-index",
    KeyConditionExpression: "subscriberKey = :subscriberKey",
    FilterExpression: "attribute_exists(mobileNumber)",
    ExpressionAttributeValues: {
        ":subscriberKey": subscriberNo
    }
};