如果条目已存在,如何防止覆盖DynamoDB项目

时间:2017-10-02 18:16:27

标签: amazon-web-services lambda amazon-dynamodb

我试图写一个lambda函数来将新数据添加到DynamoDB表中。 从阅读文档:

http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#put-property  PUT方法:"通过委托AWS.DynamoDB.putItem()创建一个新项目或用新项目替换旧项目。"

除了在放置'之前检查对象。当尝试PUT时,是否存在使对象失效的设置或标志?

我可以在

中看到
params -> Expected -> Exists (Bool)

但无法查看有关此功能的任何文档。

阻止项目覆盖的最佳架构(或禁止)是什么?

Query the table first and if no item exists then add the item

Attempt to insert the item and on failure because of duplicate entry report this back? (Is there a way to prevent item overwrite?)

3 个答案:

答案 0 :(得分:13)

var table = "Movies"; var year = 1502; var title = "The Big New Movie"; var params = { TableName:table, Item:{ "yearkey": year, "title": title, "info":{ "plot": "Nothing happens at all.", "rating": 0 } }, ConditionExpression: "yearkey <> :yearKeyVal AND #title <> :title", ExpressionAttributeNames: { "#title" : "title" }, ExpressionAttributeValues: { ":yearKeyVal" : year, ":title": {"S": title} } }; console.log("Adding a new item..."); docClient.put(params, function(err, data) { if (err) { console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2)); } else { console.log("Added item:", JSON.stringify(data, null, 2)); } }); 可用于检查表中是否已存在键属性值,并且仅当表中不存在键值时才执行PUT操作。

运行以下代码时,第一次put操作应该成功。在第二次运行中,put操作应该失败,“条件请求失败”异常。

我的电影桌有分区和排序键。所以,我在条件表达式中使用了这两个属性。

带条件的示例代码: -

Unable to add item. Error JSON: {
  "message": "The conditional request failed",
  "code": "ConditionalCheckFailedException",
  "time": "2017-10-02T18:26:26.093Z",
  "requestId": "7ae3b0c4-3872-478d-908c-94bc9492a43a",
  "statusCode": 400,
  "retryable": false,
  "retryDelay": 0
}

第二次执行放置操作时出现异常: -

+

答案 1 :(得分:4)

我看到这个问题与JavaScript语言有关,无论如何我也会写Java(也许对某人有用):

DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression();
Map<String, ExpectedAttributeValue> expectedAttributes =
        ImmutableMapParameter.<String, ExpectedAttributeValue>builder()
                .put("hashKeyAttrName", new ExpectedAttributeValue(false))
                .put("rangeKeyAttrName", new ExpectedAttributeValue(false))
                .build();
saveExpression.setExpected(expectedAttributes);
saveExpression.setConditionalOperator(ConditionalOperator.AND);

try {
    dynamoDBMapper.save(item, saveExpression);
} catch (ConditionalCheckFailedException e) {
    e.printStackTrace();
}
如果我们将尝试使用DynamoDB中现有的hashKey和rangeKey对来保存项目,则会抛出

ConditionalCheckFailedException

答案 2 :(得分:3)

作为对 notionquest 正确答案的补充,在项目已经存在的情况下表达使 putItem 失败的条件的推荐方法是断言分区键不存在于任何潜在存在的项目中:

"ConditionExpression": "attribute_not_exists(pk)",

这读作“如果此项目在 putItem 之前已经存在,请确保它没有分区键”(pk 在此示例中是分区键)。由于没有分区键,项目不可能存在,这实际上意味着“确保该项目不存在”。

另见本页开头的“注意”块:https://awscli.amazonaws.com/v2/documentation/api/latest/reference/dynamodb/put-item.html

这里有一个用于保证非键列唯一性的示例:

https://aws.amazon.com/blogs/database/simulating-amazon-dynamodb-unique-constraints-using-transactions/