Reputation: 203
I'm trying to query my DynamoDB table and convert the results to a json string.
sess, _ := session.NewSession(&aws.Config{
Region: aws.String("eu-central-1")},
)
dyn = dynamodb.New(sess)
var limit int64 = 5
out, err := dyn.Scan(&dynamodb.ScanInput{
TableName: aws.String("Products"),
Limit: &limit,
})
b, _ := json.Marshal(out.Items[0])
fmt.Println(string(b))
But the result is unfortunately filled with NULLs, and I don't want to send the whole thing over the wire:
"Price":{"B":null,"BOOL":null,"BS":null,"L":null,"M":null,"N":"17119","N
S":null,"NULL":null,"S":null,"SS":null}
I know that this has to do with the dynamo.AttributeValue type. Is it possible to omit null values?
Thank you.
Upvotes: 1
Views: 4384
Reputation: 1
this is not exactly what you ask for, but it can help you to convert a map[string]*dynamodb.AttributeValue to string without null fields.
Surely exists a better way to do this, but this is how I rapidly solve my problem with Dynamo AttributeValues nulls for now.
I hope this can help you
func GetDynamoAttributeString(newImage dto.Transaction) string {
newImageDynamoItem, _ := dynamodbattribute.MarshalMap(newImage)
newImageBytesItem, _ := json.Marshal(newImageDynamoItem)
var newImageItemMap map[string]interface{}
_ = json.Unmarshal(newImageBytesItem, &newImageItemMap)
removeNulls(newImageItemMap)
newImageStringItem, _ := json.Marshal(newImageItemMap)
return string(newImageStringItem)
}
func removeNulls(m map[string]interface{}) {
val := reflect.ValueOf(m)
for _, e := range val.MapKeys() {
v := val.MapIndex(e)
if v.IsNil() {
delete(m, e.String())
continue
}
switch t := v.Interface().(type) {
// If key is a JSON object (Go Map), use recursion to go deeper
case map[string]interface{}:
removeNulls(t)
}
}
}
Reference to remove null fields on golang maps: https://www.ribice.ba/golang-null-values/
Upvotes: 0
Reputation: 253
You can omit NULL values during marshaling by adding omitempty like this
type Person struct {
Name string
Email string `dynamodbav:",omitempty"`
Friends []string `dynamodbav:",omitemptyelem"`
}
godocs type Encoder
Upvotes: 0
Reputation: 203
So I found "an" answer but I don't know if there's a better one.
var p Product
dynamodbattribute.UnmarshalMap(out.Items[0], &p)
b, _ := json.Marshal(p)
fmt.Println(string(b))
First I unmarshal the item from DynamoDB to a Go Struct then marshal to JSON.
That seems like a lot of work, I would prefer to go from map[string]*AttributeValue
directly to a JSON string (without all these NULL
values of course)
So if somebody can come up with something more elegant, pls share.
Upvotes: 2
Reputation: 6433
You should be able to do this with JSON struct omitempty tags
type Total struct {
A *ColorGroup`json:",omitempty"`
B string`json:",omitempty"`
}
Upvotes: 0