【问题标题】:dynamodb updateitem with conditionexpression return whether item updated带有条件表达式的 dynamodb updateitem 返回项目是否已更新
【发布时间】:2020-12-05 02:01:43
【问题描述】:

我想在某些条件下更新一个项目,然后我想知道当 UpdateItem 返回时该项目是否被更新。

文档对我来说似乎是矛盾的。

在此页面上:http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html 在“条件更新”示例中显示“所有项目的属性,在更新后显示,都在响应中返回。”

在这个页面上:https://godoc.org/github.com/aws/aws-sdk-go/service/dynamodb#UpdateItemOutput 它说 Attributes 是“在 UpdateItem 操作之前出现的属性值的映射”

我真的不想要这些。我想要的是一个说明是否有更新的布尔值。

这是我现在的大脑所在:

out, err := db.DynamoDB.UpdateItem(&dynamodb.UpdateItemInput{
    TableName: tableName,
    Key: map[string]*dynamodb.AttributeValue{
        "KeyName": {S: aws.String(keyname)},
    },
    ExpressionAttributeNames: map[string]*string{
        "#lock": aws.String("Lock"),
    },
    ExpressionAttributeValues: map[string]*string{
        ":now":     aws.String(compfmt(time.Now())),
        ":promise": aws.String(compfmt(time.Now().Add(30 * time.Second))),
    },
    ConditionExpression: aws.String("attribute_not_exist(#lock) OR :now > #lock"),
    UpdateExpression:    aws.String("SET #lock = :promise"),
})

【问题讨论】:

  • 您可以使用ALL_NEWUPDATED_NEW 来获取属性中的新值。
  • 如果没有更新,UPDATED_NEW的结果会不会是空的?还是不管操作后是否返回当前值?
  • 您必须自己尝试,但如果文档正确,那么在这种情况下属性映射应该为空。
  • 谢谢!我可以为它编写测试,所以我会看看它是怎么回事并报告回来。
  • 作为参考,我使用了UPDATED_NEW,它按预期工作,但事实证明,如果 ConditionExpression 失败,则会返回错误 (ConditionalCheckFailedException),因此这同样可用于确定是否存在更新。

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


【解决方案1】:

一种方法是检查Code 上的awserr

import "github.com/aws/aws-sdk-go/aws/awserr"
func Lock()(bool, error) {
    //Create value v
    _, err := db.DynamoDB.UpdateItem(v)
    if err != nil {
         if ae, ok := err.(awserr.RequestFailure); ok && ae.Code() == "ConditionalCheckFailedException" {
             return false, nil
         }
        return false, err
    }
    return true, nil
}

【讨论】:

    【解决方案2】:

    现在有用于比较错误的常量,而不是像其他答案那样使用硬编码字符串:

    result, err := svc.UpdateItem(input)
    if err != nil {
        if aerr, ok := err.(awserr.Error); ok {
            switch aerr.Code() {
            case dynamodb.ErrCodeConditionalCheckFailedException:
                fmt.Println(dynamodb.ErrCodeConditionalCheckFailedException, aerr.Error())
            default:
                fmt.Println(aerr.Error())
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      原来我想做的是检查错误以查看它是否包含字符串ConditionalCheckFailedException

      func Lock() (bool, error) {
        ...
        _, err := db.DynamoDB.UpdateItem(v)
        if err != nil {
          if strings.Contains(err.Error(), "ConditionalCheckFailedException") {
            return false, nil
          }
          return false, err
        }
        return true, nil
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-04-13
        • 1970-01-01
        • 1970-01-01
        • 2012-05-15
        • 2021-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多