В DynamoDB у меня есть таблица, содержащая:
- email (primary key)
- password (attribute)
- rname (attribute)
Я использую V1 AWS Go SDK, чтобы выполнить запрос, используя только первичный ключ к моей базе данных:
Моя структура для unMarshal:
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
}
Однако я получаю проблему, что ключ недействителен. Я проверяю ключ в базе данных, и он совпадает с тем, который я распечатываю в консоли.
Не уверен, как обойти эту проблему, поскольку примеры, которые я видел, работают для них и выглядят одинаково.
Будем признательны за любую помощь в решении этой проблемы, спасибо :)
Вам нужно установить значения пароля и 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() {
// 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("[email protected]"),
},
},
},
},
})
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()
}
}
Более того, поскольку вы используете один ключ 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() {
// 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("[email protected]"),
},
},
})
// 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)
}
Можете ли вы поделиться выводом DescribeTable? Если на кли: aws dynamodb describe-table --table-name 'accountsTable'
Есть ли способ сделать это без CLI? Просто с помощью консоли
Если вы перейдете к своей таблице, сделаете снимок экрана с обзором своих таблиц и добавите это к своему вопросу, это сработает.
Добавил картинку стола
Спасибо, можете ли вы поделиться точным исключением?
Давайте продолжим обсуждение в чате.
Пробовал это, но, к сожалению, та же проблема. Если электронная почта является первичным ключом, должен ли я использовать Pk / pk, или все же электронная почта будет в порядке?