-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UnmarshalTypeError: cannot unmarshal map string key into Go value of type xx #3394
Comments
Thanks for reaching out to us about this @scorsi. Unfortunately I'm not able to reproduce this with the provided code since your
Can you please update the code sample to define these types so we can better troubleshoot the described behavior? |
Hello, thanks for your reply ! Sorry I didn't check if the sample works or not.. Here's a working sample: 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"
)
const tableName = "MyTable"
var (
svc *dynamodb.DynamoDB = nil
)
func init() {
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
svc = dynamodb.New(sess)
}
type MyEnum int
const (
MyEnumA MyEnum = iota
MyEnumB
)
var (
_myEnumValueToName = map[MyEnum]string{
MyEnumA: "A",
MyEnumB: "B",
}
_myEnumNameToValue = map[string]MyEnum{
"A": MyEnumA,
"B": MyEnumB,
}
)
func (t MyEnum) MarshalDynamoDBAttributeValue(av *dynamodb.AttributeValue) error {
if s, ok := _myEnumValueToName[t]; !ok {
return fmt.Errorf("invalid MyEnum: %d", t)
} else {
av.S = aws.String(s)
return nil
}
}
func (t *MyEnum) UnmarshalDynamoDBAttributeValue(av *dynamodb.AttributeValue) error {
s := aws.StringValue(av.S)
if v, ok := _myEnumNameToValue[s]; !ok {
return fmt.Errorf("invalid MyEnum %q", s)
} else {
*t = v
return nil
}
}
type MyStruct struct {
Id string
MyEnum MyEnum
MyMap map[MyEnum]bool
}
func setItem(id string) {
s := MyStruct{
Id: id,
MyEnum: MyEnumA,
MyMap: map[MyEnum]bool{
MyEnumA: true,
MyEnumB: false,
},
}
fmt.Println(s)
av, err := dynamodbattribute.MarshalMap(s)
if err != nil {
panic(err)
}
input := &dynamodb.PutItemInput{
Item: av,
TableName: aws.String(tableName),
}
_, err = svc.PutItem(input)
if err != nil {
panic(err)
}
}
func getItem(id string) {
result, err := svc.GetItem(&dynamodb.GetItemInput{
TableName: aws.String(tableName),
Key: map[string]*dynamodb.AttributeValue{
"Id": {
S: aws.String(id),
},
},
})
if err != nil {
panic(err)
}
s := MyStruct{}
err = dynamodbattribute.UnmarshalMap(result.Item, &s)
if err != nil {
panic(fmt.Sprintf("Failed to unmarshal Record, %v", err))
}
fmt.Println(s)
}
func main() {
id := "0"
setItem(id)
getItem(id)
} You just need to change You will got the following output:
If you look into your DynamoDB Table you will see the following entry: {
"Id": {
"S": "0"
},
"MyEnum": {
"S": "A"
},
"MyMap": {
"M": {
"0": {
"BOOL": true
},
"1": {
"BOOL": false
}
}
}
} As you can see, it's |
My actual work-around is to do as follow:
And removing both But I would like to have And using |
I'm having this same issue. Map keys are always converted to string when encoding. And Map decoder logic seems to raise an error if destination map's key is not a string. So basically there is no way to encode/decode maps indexed by a non-string type (e.g. https://github.com/aws/aws-sdk-go/blob/master/service/dynamodb/dynamodbattribute/encode.go#L336 |
This is something that the standard library supports in its json marshaler, so should be possible: https://play.golang.org/p/mUDdAiYZAnz Looks like this is the code for converting the key string to the correct type: https://golang.org/src/encoding/json/decode.go#L786 |
We do not have plans to add support in V1 SDK. Feel free to open a PR in the aws/aws-sdk-go-v2 SDK. This feature request is related to aws/aws-sdk-go-v2#645 and aws/aws-sdk-go-v2#411 |
|
Describe the bug
Looks like #1917 but everything I made is correct. Marshaling/unmarshalling when my enums are not in map string key with the same process are fine.
See the following example for a concret example. It looks like when marshal/unmarshall map, the string key aren't marshaled/unmarshaled and it expects to be a
string
.Version of AWS SDK for Go?
v1.32.10
Version of Go (
go version
)?go1.14.4 darwin/amd64
To Reproduce (observed behavior)
Expected behavior
I can marshal my Order but when I look into DynamoDB the key aren't marshalled, it's why it failed during unmarshaling.
The text was updated successfully, but these errors were encountered: