Go语言 具有许多属性的UpdateItem

c0vxltue  于 2023-11-14  发布在  Go
关注(0)|答案(2)|浏览(113)

我正在尝试更新一个有很多属性(超过100个)的物品。我可以看到有两种方法来更新这个物品。

PutItem:PutItem可以更新项目,根据我的理解,我需要为每个请求发送所有100个属性,因为我使用struct来编组和解组请求数据。如果我跳过任何字段,默认值将插入到表中。
UpdateItemInput:我们可以通过UpdateItemInput更新表,具体如下-

svc := dynamodb.New(session.New())
    input := &dynamodb.UpdateItemInput{
    ExpressionAttributeNames: map[string]*string{
        "#AT": aws.String("AlbumTitle"),
        "#Y":  aws.String("Year"),
    },
    ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
        ":t": {
            S: aws.String("Louder Than Ever"),
        },
        ":y": {
            N: aws.String("2015"),
        },
    },
    Key: map[string]*dynamodb.AttributeValue{
        "Artist": {
            S: aws.String("Acme Band"),
        },
        "SongTitle": {
            S: aws.String("Happy Day"),
        },
    },
    ReturnValues:     aws.String("ALL_NEW"),
    TableName:        aws.String("Music"),
    UpdateExpression: aws.String("SET #Y = :y, #AT = :t"),
}

result, err := svc.UpdateItem(input)

字符串
这里我们需要为很多属性写ExpressionAttributeNames,如果要更新的属性是动态的,我应该如何处理。
我不知道哪一种是处理更新的有效方法。请建议哪一种是更好的方法,或者有任何其他方法来处理这种情况。

u0njafvf

u0njafvf1#

你是对的,PutItem替换任何具有相同键的现有项,所以如果你只想将一堆新属性值合并到现有项中,你需要使用UpdateItem
一种选择是使用UpdateExpression语法,你需要创建一个像SET #a1 = :a1, SET #a2 = :a2, ...这样的字符串,并将它们都设置为a1等,但这并不是一个很难的编程练习。
另一种选择是使用旧的AttributeUpdates语法,而不是UpdateExpression。这可能稍微容易一些(您只需构建一个JSON列表,而不是一个表达式加两个列表),但两者都需要一些简单的编程。

nwsw7zdq

nwsw7zdq2#

这取决于你的API功能。因为你有很多属性,PutItem要求你在更新时包括所有这些属性,这样它就不会被覆盖。如果你想让API覆盖每个请求的整个项目,那么PutItem是更好的选择。但是如果你想让API只更新某些字段,而不覆盖你结构上没有的字段,那么UpdateItem是更好的选择。另外,注意,写容量将随UpdateItem与PutItem而不同。
这是我发现的一种自动为UpdateItem生成更新表达式的方法,因为手动操作似乎很繁琐。请注意,这不是最有效的方法,但在延迟方面,更喜欢非最佳延迟来自动创建更新表达式。

import (
  "encoding/json"
  "log"

  "github.com/aws/aws-sdk-go/service/dynamodb"
  "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
  "github.com/aws/aws-sdk-go/service/dynamodb/expression"
)

type Service struct {
  db        *dynamodb.DynamoDB
  tableName string
}

func Update[T any](service *Service, keyObj interface{}, obj *T) error {
  tkey, err := dynamodbattribute.MarshalMap(keyObj)
  if err != nil {
    log.Println("Error(Update):", err)
    return err
  }

  var dict map[string]interface{}
  b, _ := json.Marshal(obj)
  json.Unmarshal(b, &dict)

  var update expression.UpdateBuilder
  for key, value := range dict {
    update = update.Set(expression.Name(key), expression.Value(value))
  }

  expr, err := expression.NewBuilder().
    WithUpdate(update).
    Build()

  input := &dynamodb.UpdateItemInput{
    ExpressionAttributeNames:  expr.Names(),
    ExpressionAttributeValues: expr.Values(),
    TableName:                 &service.tableName,
    Key:                       tkey,
    UpdateExpression:          expr.Update(),
  }

  log.Printf("%v", input)

  _, err = service.db.UpdateItem(input)
  return err
}

字符串

相关问题