如何在v2 Go SDK中使用KeyConditionExpression查询AWS DynamoDb?

afdcj2ne  于 2023-11-14  发布在  Go
关注(0)|答案(1)|浏览(165)

我用以下命令在dynamodb中创建了一个现有表

  1. aws dynamodb create-table \
  2. --region us-east-1 \
  3. --table-name notifications \
  4. --attribute-definitions AttributeName=CustomerId,AttributeType=S AttributeName=Timestamp,AttributeType=N AttributeName=MessageId,AttributeType=S \
  5. --key-schema AttributeName=CustomerId,KeyType=HASH AttributeName=Timestamp,KeyType=RANGE \
  6. --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
  7. --global-secondary-indexes '[
  8. {
  9. "IndexName": "MessageId",
  10. "KeySchema": [
  11. {
  12. "AttributeName": "MessageId",
  13. "KeyType": "HASH"
  14. }
  15. ],
  16. "Projection": {
  17. "ProjectionType": "ALL"
  18. },
  19. "ProvisionedThroughput": {
  20. "ReadCapacityUnits": 5,
  21. "WriteCapacityUnits": 5
  22. }
  23. }
  24. ]'
  25. }

字符串
我想在它前面放置一个API Package 器,它允许我从CustomerId提供的表中获取所有记录,因此我尝试使用v2 GO SDK中的查询

  1. // GET /notifications/
  2. func (api NotificationsApi) getNotifications(w http.ResponseWriter, r *http.Request) {
  3. var err error
  4. customerId := r.URL.Query().Get("customerId")
  5. if customerId == "" {
  6. api.errorResponse(w, "customerId query parameter required", http.StatusBadRequest)
  7. return
  8. }
  9. span, ctx := tracer.StartSpanFromContext(r.Context(), "notification.get")
  10. defer span.Finish(tracer.WithError(err))
  11. keyCond := expression.Key("CustomerId").Equal(expression.Value(":val"))
  12. expr, err := expression.NewBuilder().WithKeyCondition(keyCond).Build()
  13. input := &dynamodb.QueryInput{
  14. TableName: aws.String("notifications"),
  15. KeyConditionExpression: expr.KeyCondition(),
  16. ExpressionAttributeValues: map[string]dynamodbTypes.AttributeValue{
  17. ":val": &dynamodbTypes.AttributeValueMemberS{Value: customerId},
  18. },
  19. }
  20. fmt.Println(*expr.KeyCondition())
  21. output, err := api.dynamoClient.Query(ctx, input)
  22. fmt.Println(output)
  23. fmt.Println(err)
  24. }


但是,我从dynamodb得到了400分。

  1. operation error DynamoDB: Query, https response error StatusCode: 400, RequestID: *****, api error ValidationException: Invalid KeyConditionExpression: An expression attribute name used in the document path is not defined; attribute name: #0


fmt.PrintLn(*expr.KeyCondition())的输出是#0 = :0
在本地运行此查询将返回预期结果

  1. awslocal dynamodb query \
  2. --table-name notifications \
  3. --key-condition-expression "CustomerId = :val" \
  4. --expression-attribute-values '{":val":{"S":"localTesting"}}'


我也试过包含时间戳,但不认为这是必需的,因为我的终端命令没有它的作品。我不认为我解引用不当。我知道我的发电机会话是有效的,因为我可以张贴到我的 Package 器,并通过终端命令看到更新。

p8h8hvxi

p8h8hvxi1#

下面是一个可以用作模板的查询示例:

  1. // TableBasics encapsulates the Amazon DynamoDB service actions used in the examples.
  2. // It contains a DynamoDB service client that is used to act on the specified table.
  3. type TableBasics struct {
  4. DynamoDbClient *dynamodb.Client
  5. TableName string
  6. }
  7. // Query gets all movies in the DynamoDB table that were released in the specified year.
  8. // The function uses the `expression` package to build the key condition expression
  9. // that is used in the query.
  10. func (basics TableBasics) Query(releaseYear int) ([]Movie, error) {
  11. var err error
  12. var response *dynamodb.QueryOutput
  13. var movies []Movie
  14. keyEx := expression.Key("year").Equal(expression.Value(releaseYear))
  15. expr, err := expression.NewBuilder().WithKeyCondition(keyEx).Build()
  16. if err != nil {
  17. log.Printf("Couldn't build expression for query. Here's why: %v\n", err)
  18. } else {
  19. response, err = basics.DynamoDbClient.Query(context.TODO(), &dynamodb.QueryInput{
  20. TableName: aws.String(basics.TableName),
  21. ExpressionAttributeNames: expr.Names(),
  22. ExpressionAttributeValues: expr.Values(),
  23. KeyConditionExpression: expr.KeyCondition(),
  24. })
  25. if err != nil {
  26. log.Printf("Couldn't query for movies released in %v. Here's why: %v\n", releaseYear, err)
  27. } else {
  28. err = attributevalue.UnmarshalListOfMaps(response.Items, &movies)
  29. if err != nil {
  30. log.Printf("Couldn't unmarshal query response. Here's why: %v\n", err)
  31. }
  32. }
  33. }
  34. return movies, err
  35. }

字符串
你可以在这里看到更多的GoV2示例

展开查看全部

相关问题