aws / aws-sdk-go-v2

AWS SDK for the Go programming language.
https://aws.github.io/aws-sdk-go-v2/docs/
Apache License 2.0
2.68k stars 651 forks source link

Flattening out dynamodbattribute.MarshalMap results #2756

Closed nathannaveen closed 3 months ago

nathannaveen commented 3 months ago

Acknowledgements

Describe the bug

We need a way to convert an a raw json to an object like this []map[string]types.attributevalue using the attributevalue package.

I am trying to use dynamodbattribute.MarshalMap to accomplish this. But, when I do this, the maps aren't flattened, and our usage requires the maps flattened because we're querying dynamo using a step function and passing the results into a lambda.

Here is an example:

package main

import (
    "fmt"
    "log"
    "strings"

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

type Item struct {
    Title       string                 `json:"title"`
    Rating      float64                `json:"rating"`
    NestedField map[string]interface{} `json:"nestedField"`
}

func main() {
    item := Item{
        Title:  "test1",
        Rating: 8.5,
        NestedField: map[string]interface{}{
            "key1": "value1",
            "key2": map[string]interface{}{
                "key3": "value2",
            },
        },
    }

    av, err := dynamodbattribute.MarshalMap(item)
    if err != nil {
        log.Fatalf("Got error marshalling map: %s", err)
    }

    var avStr string
    for k, v := range av {
        avStr += fmt.Sprintf("%s:%+v ", k, v)
    }

    fmt.Println(strings.TrimSpace(avStr))
}

Is there already way to flatten out the maps? Or is there a work around for this?

Expected Behavior

We would like the maps to be flattened out because we're querying dynamo using a step function and passing the results into a lambda.

Current Behavior

dynamodbattribute.MarshalMap outputs maps that aren't flattened.

Reproduction Steps

Here's an example:

package main

import (
    "fmt"
    "log"
    "strings"

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

type Item struct {
    Title       string                 `json:"title"`
    Rating      float64                `json:"rating"`
    NestedField map[string]interface{} `json:"nestedField"`
}

func main() {
    item := Item{
        Title:  "test1",
        Rating: 8.5,
        NestedField: map[string]interface{}{
            "key1": "value1",
            "key2": map[string]interface{}{
                "key3": "value2",
            },
        },
    }

    av, err := dynamodbattribute.MarshalMap(item)
    if err != nil {
        log.Fatalf("Got error marshalling map: %s", err)
    }

    var avStr string
    for k, v := range av {
        avStr += fmt.Sprintf("%s:%+v ", k, v)
    }

    fmt.Println(strings.TrimSpace(avStr))
}

Possible Solution

No response

Additional Information/Context

No response

AWS Go SDK V2 Module Versions Used

github.com/aws/aws-sdk-go-v2 v1.30.3 github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.14.10

Compiler and Version used

go version go1.22.4 darwin/arm64

Operating System and version

macOS Sonoma Version 14.4

RanVaknin commented 3 months ago

Hi @nathannaveen,

Thanks for reaching out. The DynamoDB marshaller (dynamodbattribute.MarshalMap) is designed to convert Go data types into DynamoDB AttributeValue types while preserving the original structure. Modifying it to 'flatten' nested maps would fundamentally alter its purpose and break the expected relationship between Go structs and DynamoDB items.

The current marshaller's implementation maintains the nested structure of the map, which is how DynamoDB expects to store and retrieve complex objects. If you need a flattened structure for your specific use case, that transformation should be handled separately in your application logic.

Thanks, Ran~

nathannaveen commented 3 months ago

Ok, thank you for the help @RanVaknin!

github-actions[bot] commented 3 months ago

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.