微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Step 函数中的 dynamodb ConditionExpression

如何解决Step 函数中的 dynamodb ConditionExpression

通过使用 aws-step-functions,我试图将 putItem 转化为 dynamodb

这是 .yml 的摘录,它按预期工作。

...

AddingURLs:
  Type: Map
  ItemsPath: "$.vidPosts"
  Parameters:
    vidPostsIndex.$: "$$.Map.Item.Index" 
      vidPosts.$: "$$.Map.Item.Value"

  Iterator:
    StartAt: AddingURLIntoDynamoDB
    Comment: Looping over urls and adding them into the db

    States:
      AddingURLIntoDynamoDB:
        Type: Task
        Resource: arn:aws:states:::dynamodb:putItem
        ResultPath: null
        Parameters:
          TableName: my-table-table-name
          Item:
            videoID:
              S.$: "$.vidPosts.[0]"
            urls:
              S.$: "$.vidPosts.[1]"
          ConditionExpression: "attribute_not_exists(videoID)"    

        End: true

  Next: EndStepFunctions

EndStepFunctions:
  Comment: This marks the end of a step functions
  Type: Succeed

但是下一次,当这个状态被调用时,如果它遇到一个已经存在的条目,因为ConditionExpression: "attribute_not_exists(videoID)",它应该抛出,

{
  executionArn: 'arn:aws:states:us-east-2:aaabbbccc:execution:xxxStateMachine:XXX-YYY-ZZZ',stateMachineArn: 'arn:aws:states:us-east-2:aaabbbccc:stateMachine:xxxStateMachine',name: '9814ce93-bc42-4f31-a742-089ea7db9ad6',status: 'Failed',startDate: 2021-03-18T15:30:45.912Z,stopDate: 2021-03-18T15:30:52.386Z,input: '{}',inputDetails: { included: true },error: 'DynamoDB.ConditionalCheckFailedException',cause: 'The conditional request Failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: bfd76f51-567b-439c-9a39-5a1643e75a69; Proxy: null)'
}

我的问题是在 aws-step-functions 内,如何让它忽略现有条目但继续使用迭代器?

感谢任何帮助并提前感谢您。

解决方法

我们只需要捕获 DynamoDB.ConditionalCheckFailedException 异常并继续前进,而不会抛出任何错误。

我们需要的是

  "Catch": [
    {
      "ErrorEquals": [
        "DynamoDB.ConditionalCheckFailedException"
      ],"Next": "FinalStep"
    }
  ]

这里是全步函数。

{
  "StartAt": "put-item","States": {
    "put-item": {
      "Next": "FinalStep","Catch": [
        {
          "ErrorEquals": [
            "DynamoDB.ConditionalCheckFailedException"
          ],"Next": "FinalStep"
        }
      ],"Type": "Task","Resource": "arn:aws:states:::dynamodb:putItem","Parameters": {
        "Item": {
          "pk": {
            "S": "1"
          },"test": {
            "S": "value"
          }
        },"TableName": "test","ConditionExpression": "attribute_not_exists(#videoID)","ExpressionAttributeNames": {
          "#videoID": "videoID"
        }
      }
    },"FinalStep": {
      "Type": "Pass","End": true
    }
  }
}

Put-item 因错误而失败,仍移至下一个任务。

{
  "Error": "DynamoDB.ConditionalCheckFailedException","Cause": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: xxxx-xxx-xxx-xxx-xxxxx; Proxy: null)"
}

enter image description here

,

我认为你有几个选择。

  1. 不要在 putItem 上设置条件。如果数据相同,那么您可以让它用新数据覆盖数据,这不会真正改变任何东西。请记住,putItem 与 SQL INSERT 不同。它更像是一个 UPSERT
  2. 在您的步骤中添加一个 Catch 块,并让它继续到与成功案例相同的位置。如果您希望 Pass 的输出中的某些内容在下一步的输入中,您可能需要先使其进入 putItem 状态。
  3. 在执行 get 的 put 之前添加一个步骤,然后在条件步骤上执行 put。如果在某些情况下您可以在很近的范围内获得对同一记录的多次调用,这可能不是最佳选择,因为您可能都点击了 get 而没有看到记录,然后两者都会执行 put(在这种情况下失败)。如果您永远不会遇到这种情况,那么这会奏效。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。