首页 > 解决方案 > 具有多个条件的 DynamoDB 事务插入(PK/SK attribute_not_exists 和 SK attribute_exists)

问题描述

我有一个带有 PK(字符串)和 SK(整数)的表 - 例如

PK_id                   SK_version      Data
-------------------------------------------------------
c3d4cfc8-8985-4e5...    1               First version
c3d4cfc8-8985-4e5...    2               Second version

我可以进行条件插入以确保我们不会使用 ConditionalExpression(在 GoLang SDK 中)覆盖 PK/SK 对:

putWriteItem := dynamodb.Put{
    TableName:                           "example_table",
    Item:                                itemMap,
    ConditionExpression:                 aws.String("attribute_not_exists(PK_id) AND attribute_not_exists(SK_version)"),
}

但是,我还想确保 SK_version 始终是连续的,但不知道如何编写表达式。在伪代码中是:

putWriteItem := dynamodb.Put{
    TableName:                           "example_table",
    Item:                                itemMap,
    ConditionExpression:                 aws.String("attribute_not_exists(PK_id) AND attribute_not_exists(SK_version) **AND attribute_exists(SK_version = :SK_prev_version)**"),
}

有人可以建议我怎么写这个吗?

在 SQL 中,我会做类似的事情:

INSERT INTO example_table (PK_id, SK_version, Data)
SELECT {pk}, {sk}, {data}
WHERE NOT EXISTS (
                    SELECT  1 
                    FROM    example_table
                    WHERE   PK_id = {pk}
                       AND  SK_version = {sk}
                 )
   AND EXISTS    (
                    SELECT  1
                    FROM    example_table
                    WHERE   PK_id = {pk}
                       AND  SK_version = {sk} - 1
                 )

谢谢

标签: amazon-dynamodbdynamodb-queries

解决方案


条件检查应用于单个项目。它不能跨越多个项目。换句话说,您只需要多个条件检查。DynamoDb 具有执行多个条件检查以及写入/删除的transactWriteItems API。下面的代码在 nodejs 中。

  const previousVersionCheck = {
    TableName: 'example_table',
    Key: {
      PK_id: 'prev_pk_id',
      SK_version: 'prev_sk_version'
    },
    ConditionExpression: 'attribute_exists(PK_id)'
  }

  const newVersionPut = {
    TableName: 'example_table',
    Item: {
      // your item data
    },
    ConditionExpression: 'attribute_not_exists(PK_id)'
  }

  await documentClient.transactWrite({
    TransactItems: [
      { ConditionCheck: previousVersionCheck },
      { Put: newVersionPut }
    ]
  }).promise()

事务有 2 个操作:一个是对先前版本的验证,另一个是条件写入。他们的任何条件检查失败,交易失败。


推荐阅读