【问题标题】:DynamoDB: updateItem only if it already existsDynamoDB:仅当它已经存在时才更新项目
【发布时间】:2021-04-24 02:42:17
【问题描述】:

默认情况下,如果具有指定索引的对象不存在,DynamoDB 将创建一个新条目。有没有办法阻止这种情况发生?我可以在更新之前在表中查询密钥,但最好在一个请求中完成所有操作。

【问题讨论】:

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


【解决方案1】:

使用条件表达式id = :id,其中id 是属性名称(在您的情况下是主键名称),:id 是值(您要更新的项目的键)。

条件表达式总是在任何写入之前进行评估。如果该表达式的计算结果不是true(并且如果该键不存在或不同,则不会),它不会更新或放置新项目。

【讨论】:

    【解决方案2】:

    关键是 ConditionExpression 根据您正在执行的操作在不同的数据集上进行审查PutItemUpdateItem

    PutItem。

    在设置ConditionExpression 时,DynamoDB 将检查您在任何 Key 行上的条件 - 如果在表上使用范围属性,则为多行,如果仅对表使用散列,则仅检查 1 行 -。

    请记住,DynamoDB PutItem 操作必须检查您传递的密钥是否已经存在,因此在这里检查您的条件无需额外费用。

    例如,如果您有一个带有 customer_id/contact_email 键定义的 CUSTOMER_CONTACTS 表,并且不想创建重复项,则可以设置 ConditionExpression = "#contact_email <> :email"。在这种情况下,如果将相同的电子邮件(范围属性)用于指定的哈希值,则 PutItem 操作将失败并出现 ConditionalCheckFailedException。

    但不要期望检查远离散列行的项目属性。 DynamoDB 扫描所有表只是为了检查您的状况是没有意义的。

    更新项目。

    如果您尝试与上一个示例ConditionExpression = "#contact_email <> :email" 相同的条件,则操作始终会覆盖而不触发异常。为什么?因为 UpdateItem 只查看一项,即您的 Key 指定的一项。

    使用 UpdateItem 时,ConditionExpression 将只查看 1 行,即您必须设置的 Key 值指定的行。无法在任何其他表格行上检查您的状况。

    【讨论】:

      【解决方案3】:

      为了给出 Solo 答案的更具体示例,以下将是更新项目的 CLI 命令,该命令使用条件表达式确保在执行更新之前该行存在。

      如果使用的 ID 不存在,这会阻止 DynamoDB 创建新记录。

      aws dynamodb update-item \
          --table-name ProductCatalog \
          --key '{"Id": {"N": "456"}}' \
          --update-expression "SET Price = :price" \
          --condition-expression "id = :id" \
          --expression-attribute-values file://values.json
      

      使用包含以下内容的 values.json:

      {
          ":price": { "N": "75"},
          ":id": {"N": "456"}
      }
      

      【讨论】:

        【解决方案4】:

        您可能正在寻找attribute_not_exists 签入Condition Expressions

        当此条件表达式与 PutItem 一起使用时,DynamoDB 首先查找其主键与要写入的项目的主键匹配的项目。只有当搜索什么都不返回时,结果中才没有分区键。否则上面的attribute_not_exists函数会失败,会阻止写

        更多信息请访问http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.SpecifyingConditions.html

        【讨论】:

        • 从文档中看到attribute_not_exists 检查一行是否具有某个属性,而不是具有该键的行是否存在。是这样吗?我不想使用attribute_exists,因为我希望它在已经存在的情况下更新行,如果没有找到则什么都不做?
        • 你说得对 Bananable,我尝试使用'attribute_exists',它绝对不会阻止插入项目,因为它只检查一行是否具有特定属性。你找到解决办法了吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-11
        • 2021-02-20
        • 1970-01-01
        • 1970-01-01
        • 2013-06-14
        • 1970-01-01
        相关资源
        最近更新 更多