DynamoDB 条件表达式能否仅作用于具有复合键的表的分区键

Mat*_*att 4 amazon-dynamodb

我有一个带有复合键的 DynamoDB 表,如下所示:

PK SK 类型 电子邮件 描述
用户#A 用户#A 用户 a@example.com
用户#A 错误#1 漏洞 这看起来不错
用户#B 错误#2 漏洞 我的用户不是首先创建的!

我想确保在添加相关的“Bug”记录之前存在“User”记录 - 所以这里的第三项是不正确的。

当我将bug 项目与条件放在一起attribute_exists(PK)时,条件永远不会为真。当我删除条件时,我最终得到第三行;没有对应用户的错误。

我的理解是,attribute_exists()无论您提供哪个属性,都只查看具有组合复合键的项目,而不是整个表。

在这种情况下,是否有一种方法可以确保存在具有相同分区键的项目,同时忽略排序键?

Set*_*gan 5

DynamoDB 条件表达式可能会令人困惑,而文档可能会加剧该问题!

DynamoDB 条件表达式的工作原理是:1) 查找项目,2) 评估条件表达式,最后 3) 如果条件评估为 true,则写入数据库。

我假设你的put操作看起来像这样:

ddbClient.put({
  TableName: "YOUR TABLE",
  Item: {
    PK: "USER#B",
    SK: "BUG#2",
    Type "Bug",
    Description: "My user wasn't created first!"
  },
  ConditionExpression: "attribute_exists(PK)"
})
Run Code Online (Sandbox Code Playgroud)

在此示例中,DynamoDB 首先尝试查找 PK: "USER#B" SK: "BUG#2" 的项目,但该项目不存在。正如您所遇到的,该项目不会写入DynamoDB,因为具有该主键的项目不存在。

正如您在问题中提到的,您看到的问题是 aCondttionExpression仅适用于单个项目。但是,您尝试通过将条件应用于另一个put项目来对数据库中的一个项目进行条件化。这是 DynamoDB事务的绝佳候选者。

事务使您可以将操作分组到“全有或全无”操作中。如果事务中的一项操作失败,则整个事务将失败并且所有操作都不会应用。

通过采取这种方法,您可以实现您所追求的目标

ddbClient.transactWriteItems({
    TransactItems=[
    { "PUT":
        {
          TableName: "YOUR TABLE",
          Item: {
            PK: "USER#B",
            SK: "BUG#2",
            Type "Bug"
          }
        }
    },
    { "ConditionCheck":
        {
          TableName: "YOUR TABLE",
          Item: {
            PK: "USER#B",
            SK: "USER#B"
          },
          ConditionExpression: "attribute_exists(PK)"
        }
    }
  ]

})
Run Code Online (Sandbox Code Playgroud)

在上面的事务中,我在输入错误之前使用ConditionCheck来确认用户的存在。如果用户不存在,则事务将失败,并且错误不会写入DDB。

有关 DynamoDB 条件表达式的更全面说明,我强烈建议您查看Alex Debrie 撰写的了解 DynamoDB 条件表达式