简体   繁体   中英

Using struct to update values

I'm stuck when I'm updating an empty string values in a struct for updating dynamodb table.

Currently I have this struct

type Client struct {
    ClientID       *string    `json:"client_key,omitempty"`
    Name           *string    `json:"client_name,omitempty"`
    Address        *string    `json:"address,omitempty"`
    Country        *string    `json:"country,omitempty"`
    City           *string    `json:"city,omitempty"`
    State          *string    `json:"state,omitempty"`
    PostCode       *string    `json:"post_code,omitempty"`
    CreatedAt      *time.Time `json:"created_at,omitempty"`
}

And this code when updating an item

keyAttr, err := dynamodbattribute.MarshalMap(key)
if err != nil {
    return nil, err
}
valAttr, err := dynamodbattribute.MarshalMap(attributes)
if err != nil {
    return nil, err
}

keyAttr will be used for the Key field and valAttr will be used in ExpressionAttributeValues field. Note that I didn't include the complete updating fields function to save space. But I will do that if you ask for it.

Currently the function is running fine except when I updated one of the field with empty string. Eg client.Address = aws.String("") . While I'm fine with dynamodb converting my empty string to null , I can't seem to find a way to update it because of the omitempty tag.

I need the omitempty tag to ignore all nil values. However, I just researched that the omitempty tag also omits empty string values. Currently I have to make a struct in my function like this.

type client struct {
    Name     *string `json:"client_name"`
    Address  *string `json:"address"`
    Country  *string `json:"country"`
    City     *string `json:"city"`
    State    *string `json:"state"`
    PostCode *string `json:"post_code"`
}

But i'm not a fan of repeating things. So, the question is: is there any better way of doing this? How do you guys use structs with dynamodb?

EDIT

Based on @Peter's comment, it seems that json.Encode() does print the empty string if it's not nil.

{"client_key":"test","username":"test","email":"","first_name":"test","last_name":"","phone":"","title":"","email_verified":false,"phone_verified":false,"updated_at":"2018-12-06T14:04:56.2743841+11:00"}

The problem seems to be in dynamodbattribute.MarshalMap function

After several trials, I finally got it. I didn't test it so I don't know whether it's buggy or not. But it seems to work for me right now.

So what I did was encode the struct with json.Marshal first then use json.Unmarshal with a map[string]interface{} . Then, I use dynamodbattribute.Marshal to convert it to map[string]*AttributeValue

Here's the code:

var temp map[string]interface{}
json.Unmarshal(tempStr, &temp)
valAttr, err := dynamodbattribute.MarshalMap(temp)
if err != nil {
    return nil, err
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM