如何修复 DynamoDB 查询请求的错误?

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

How to fix error with Query dynamodb request?

问题

在DynamoDB中,我有一个包含以下内容的表:

- email(主键)
- password(属性)
- rname(属性)

我正在使用AWS Go SDK的V1版本,使用只使用主键执行查询的方式来访问我的数据库:

我用于解组的结构体是:

type Item struct {
	Email    string `json:"email"`
	Password string `json:"password"`
	Rname    string `json:"rname"`
}

代码如下:

result, err := client.Query(&dynamodb.QueryInput{
	TableName: aws.String("accountsTable"),
	KeyConditions: map[string]*dynamodb.Condition{
		"email": {
			ComparisonOperator: aws.String("EQ"),
			AttributeValueList: []*dynamodb.AttributeValue{
				{
					S: aws.String(email),
				},
			},
		},
	},
})
if err != nil {
	return false, err
}

item := []Item{}

err = dynamodbattribute.UnmarshalListOfMaps(result.Items, &item)
if err != nil {
	return false, err
}

然而,我遇到了键无效的问题。我检查了数据库中的键,发现它与我在控制台上打印出来的键是匹配的。

不确定如何解决这个问题,因为我看到的示例似乎对它们有效,并且看起来相同。

如果能帮助解决这个问题,将不胜感激 如何修复 DynamoDB 查询请求的错误?

如何修复 DynamoDB 查询请求的错误?

英文:

In DynamoDB I Have a table that contains:

- email (primary key)
- password (attribute)
- rname (attribute)

I'm using V1 of the AWS Go SDK, to implement to perform a query using just the primary key to my database:

My struct to unMarshal to is:

type Item struct {
	Email    string `json:"email"`
	Password string `json:"password"`
	Rname    string `json:"rname"`
}

and the code:

result, err := client.Query(&dynamodb.QueryInput{
		TableName: aws.String("accountsTable"),
		KeyConditions: map[string]*dynamodb.Condition{
			"email": {
				ComparisonOperator: aws.String("EQ"),
				AttributeValueList: []*dynamodb.AttributeValue{
					{
						S: aws.String(email),
					},
				},
			},
		},
	})
	if err != nil {
		return false, err
	}

	item := []Item{}

	err = dynamodbattribute.UnmarshalListOfMaps(result.Items, &item)
	if err != nil {
		return false, err
	}

However, I get the issue that the key is invalid. I check the key in the database and it matches the one i print out to the console too.

Not sure how to get round this issue as example's i've seen seem to work for their's and look the same.

Any help in fixing this issue would be appreciated thanks 如何修复 DynamoDB 查询请求的错误?

如何修复 DynamoDB 查询请求的错误?

答案1

得分: 1

你需要将password和rname的值设置为omitempty,这样它们就不会被设置为空值,因为它们不是键,不应该包含在查询中,否则会抛出无效键异常:

type Item struct {
    Email    string `json:"email" dynamodbav:"email,omitempty"`
    Password string `json:"password" dynamodbav:"password,omitempty"`
    Rname    string `json:"rname" dynamodbav:"rname,omitempty"`
}

更新

我认为问题是因为你尝试在单个命令中对整个响应进行编组,但是迭代对我有效(我不使用Go)。

package main
import (
    "github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/dynamodb"
	"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"

	"fmt"
)


func main() {

	// 创建会话
	sess := session.Must(session.NewSessionWithOptions(session.Options{
		SharedConfigState: session.SharedConfigEnable,
	}))

	// 创建带有日志记录的DynamoDB客户端
	client := dynamodb.New(sess, aws.NewConfig())


	type Item struct {
		Email    string `dynamodbav:"email"`
		Password string `dynamodbav:"password,omitempty"`
		Rname    string `dynamodbav:"rname,omitempty"`
	}

	result, err := client.Query(&dynamodb.QueryInput{
        TableName: aws.String("accountsTable"),
        KeyConditions: map[string]*dynamodb.Condition{
            "email": {
                ComparisonOperator: aws.String("EQ"),
                AttributeValueList: []*dynamodb.AttributeValue{
                    {
                        S: aws.String("lhnng@amazon.com"),
                    },
                },
            },
        },
    })

    if err != nil {
        fmt.Println("查询API调用失败:")
        fmt.Println((err.Error()))
    }



	for _, i := range result.Items {
		
		item := Item{}
		err = dynamodbattribute.UnmarshalMap(i, &item)
	
		if err != nil {
			fmt.Println("解组时出错:%s", err)
		}
	
		fmt.Println("Email: ", item.Email)
		fmt.Println()
		
	}
}

此外,由于你使用了单个键email,这意味着具有相同电子邮件地址的项目最多只有1个,因此应该使用GetItem而不是Query

package main

import (
	"fmt"

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

func main() {

	// 要获取的项目
	type Item struct {
		Email    string `dynamodbav:"email"`
		Password string `dynamodbav:"password,omitempty"`
		Rname    string `dynamodbav:"rname,omitempty"`
	}

	// 创建会话
	sess := session.Must(session.NewSessionWithOptions(session.Options{
		SharedConfigState: session.SharedConfigEnable,
	}))

	// 创建DynamoDB客户端
	client := dynamodb.New(sess, aws.NewConfig())

	// 获取项目
    result, err := client.GetItem(&dynamodb.GetItemInput{
        TableName: aws.String("accountsTable"),
        Key: map[string]*dynamodb.AttributeValue{
            "email": {
                S: aws.String("lhnng@amazon.com"),
            },
        },
    })

	// 捕获错误
	if err != nil {
		fmt.Println("GetItem API调用失败:")
		fmt.Println((err.Error()))
	}

	item := Item{}

	// 反序列化
    err = dynamodbattribute.UnmarshalMap(result.Item, &item)

    if err != nil {
        panic(fmt.Sprintf("解组记录失败,%v", err))
    }

	// 如果项目为空
    if item.Email == "" {
        fmt.Println("找不到项目")
        return
    }

	// 打印结果
    fmt.Println("找到项目:")
    fmt.Println("Email:  ", item.Email)

}
英文:

You need to set the values of password and rname to omitempty so that it's not set to empty values as they are not keys they should not be included on a Query as it throws an invalid key exception:

type Item struct {
Email    string `json:"email" dynamodbav:"email,omitempty"`
Password string `json:"password" dynamodbav:"password,omitempty"`
Rname    string `json:"rname" dynamodbav:"rname,omitempty"`
}

Update

I believe the issue is due to the fact you try to marshall the entire response in a single command, however, iterating works for me. (I do not use Go).

package main
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
"fmt"
)
func main() {
// Create Session
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
// Create DynamoDB Client with Logging
client := dynamodb.New(sess, aws.NewConfig())
type Item struct {
Email    string `dynamodbav: "email"`
Password string `dynamodbav: "password,omitempty"`
Rname    string `dynamodbav: "rname,omitempty"`
}
result, err := client.Query(&dynamodb.QueryInput{
TableName: aws.String("accountsTable"),
KeyConditions: map[string]*dynamodb.Condition{
"email": {
ComparisonOperator: aws.String("EQ"),
AttributeValueList: []*dynamodb.AttributeValue{
{
S: aws.String("lhnng@amazon.com"),
},
},
},
},
})
if err != nil {
fmt.Println("Query API call failed:")
fmt.Println((err.Error()))
}
for _, i := range result.Items {
item := Item{}
err = dynamodbattribute.UnmarshalMap(i, &item)
if err != nil {
fmt.Println("Got error unmarshalling: %s", err)
}
fmt.Println("Email: ", item.Email)
fmt.Println()
}
}

Moreover, as you use a single key of email, it means there is at most 1 item with the same email address, meaning you should use GetItem rather than Query:

package main
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
)
func main() {
// Item to Get
type Item struct {
Email    string `dynamodbav: "email"`
Password string `dynamodbav: "password,omitempty"`
Rname    string `dynamodbav: "rname,omitempty"`
}
// Create Session
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
// Create DynamoDB Client
client := dynamodb.New(sess, aws.NewConfig())
// Get Item
result, err := client.GetItem(&dynamodb.GetItemInput{
TableName: aws.String("accountsTable"),
Key: map[string]*dynamodb.AttributeValue{
"email": {
S: aws.String("lhnng@amazon.com"),
},
},
})
// Catch Error
if err != nil {
fmt.Println("GetItem API call failed:")
fmt.Println((err.Error()))
}
item := Item{}
// Unmarhsall
err = dynamodbattribute.UnmarshalMap(result.Item, &item)
if err != nil {
panic(fmt.Sprintf("Failed to unmarshal Record, %v", err))
}
// If Item Returns Empty
if item.Email == "" {
fmt.Println("Could not find Item")
return
}
// Print Result
fmt.Println("Found item:")
fmt.Println("Email:  ", item.Email)
}

huangapple
  • 本文由 发表于 2023年1月5日 09:09:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75012923.html
匿名

发表评论

匿名网友

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

确定