dynamodb updateitem with conditionexpression return whether item updated

huangapple go评论85阅读模式
英文:

dynamodb updateitem with conditionexpression return whether item updated

问题

我想在特定条件下更新一个项目,然后我想知道当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"),
})
英文:

I would like to update an item under certain conditions and then I would like to know whether the item was updated when UpdateItem returns.

The documentation seems contradictory to me.

On this page: http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html in the "Conditional Update" example it says "All of the item's attributes, as they appear after the update, are returned in the response."

On this page: https://godoc.org/github.com/aws/aws-sdk-go/service/dynamodb#UpdateItemOutput it says that Attributes is "A map of attribute values as they appeared before the UpdateItem operation"

I don't really want either of these. What I want is a bool that says whether or not there was an update.

This is where my brain is at now:

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

答案1

得分: 3

一种方法是检查awserr上的Code

import "github.com/aws/aws-sdk-go/aws/awserr"

func Lock() (bool, error) {
    // 创建值 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
}
英文:

One way to do this is to check the Code on the 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

得分: 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())
        }
    }
}

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

英文:

There are now constants to compare the errors rather than using the hardcoded string as in other answers:

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

得分: 0

原来我想要做的是检查错误,看看它是否包含字符串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
}
英文:

Turns out what I wanted to do was check the error to see if it contained the string 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
}

huangapple
  • 本文由 发表于 2016年3月26日 05:13:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/36228130.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定