代码之家  ›  专栏  ›  技术社区  ›  Matt

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

  •  0
  • Matt  · 技术社区  · 5 年前

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

    SK公司 类型 电子邮件
    用户#A 用户 a@example.com
    用户#A 错误1 缺陷 这看起来不错
    用户#B 错误2 缺陷 我的用户不是第一个创建的!

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

    attribute_exists(PK) ,条件永远不成立。当我去掉这个条件时,我就得到了第三行的结果;没有相应用户的错误。

    我的理解是 attribute_exists()

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

    1 回复  |  直到 5 年前
        1
  •  1
  •   Seth Geoghegan    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)"
    })
    

    在本例中,DynamoDB首先尝试查找PK:“USER#B”SK:“BUG#2”不存在的项。如您所体验的,此项目将 无法写入DynamoDB,因为不存在具有该主键的项。

    CondttionExpression 仅适用于 项目。但是,您正在尝试有条件地 通过将条件应用于 另一个 transaction .

    你可以通过这种方法来实现你的目标

    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)"
            }
        }
      ]
    
    })
    

    ConditionCheck 在输入错误之前确认用户的存在。如果用户不存在,事务将失败,错误将不会写入DDB。

    要更全面地解释DynamoDB条件表达式,我强烈建议您 Understanding DynamoDB Condition Expressions 亚历克斯·德布里。