英文:
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
}
然而,我遇到了键无效的问题。我检查了数据库中的键,发现它与我在控制台上打印出来的键是匹配的。
不确定如何解决这个问题,因为我看到的示例似乎对它们有效,并且看起来相同。
如果能帮助解决这个问题,将不胜感激
英文:
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
答案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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论