Home > OS >  How to fix error with Query dynamodb request?
How to fix error with Query dynamodb request?

Time:01-05

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 :)

Table Details

CodePudding user response:

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("[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()
        
    }
}

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("[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)

}


  • Related