Re: [go-nuts] Marshalling sql.NullString to JSON

2,375 views
Skip to first unread message

Jesse McNelis

unread,
Nov 22, 2012, 7:25:33 PM11/22/12
to Nikolai, golang-nuts
On Fri, Nov 23, 2012 at 4:39 AM, Nikolai <niko...@gmail.com> wrote:
I have a struct:

type Customer struct {
  Id    int64
  Name  sql.NullString
} 
Is there some clever way to get only the needed data? NULL values can be empty strings:

[{"Id":1,"Name":"John"}, {"Id":2,"Name":""}]

You'll need to make Customer satisfy the json.Marshaler interface

 


--
=====================
http://jessta.id.au


Nikolai

unread,
Nov 23, 2012, 3:37:59 AM11/23/12
to golan...@googlegroups.com, Nikolai, jes...@jessta.id.au
Thanks Jesse for the reply. I'll have to duplicate every field one more time though, additionally to the "fetch" method. But it's ok for now.

-Nikolai

Angel Medrano

unread,
Aug 30, 2014, 7:14:21 PM8/30/14
to golan...@googlegroups.com, niko...@gmail.com, jes...@jessta.id.au
Doesnt work if the struct is in a map

greg.ro...@gmail.com

unread,
Aug 31, 2014, 1:12:45 AM8/31/14
to golan...@googlegroups.com
I recently wrote a small library that does just this.
Feel free to use it or borrow the technique. Basically I embed sql.NullString in a new type and implement json.Marshaler (actually encoding.TextMarshaler) for it. 
You can just replace your sql.NullStrings with a null.String.

I'm still considering what to do with Int types. I will probably make the current Int type write 0 values in JSON, and make another type that writes nulls. But I am happy with how nullable strings work for now. 

On Friday, November 23, 2012 2:39:54 AM UTC+9, Nikolai wrote:
Hello!

I'm  trying to handle a trivial case but sql.NullString makes it rather complicated.

I have a struct:

type Customer struct {
  Id    int64
  Name  sql.NullString
}

which is loaded from a database like this:

func (c *Customer) fetch(rows *sql.Rows) error {
  return rows.Scan(&c.Id, &c.Name)
}

Customer.Name (supposedly) has to be a sql.NullString because the database has NULL values in that fields which caused error if Customer.Name was a string type.

However, json.Marshal(customer) produces some unwanted JSON with both String and Valid fields from sql.NullString:

[{"Id":1,"Name":{"String":"John","Valid":true}}]

Is there some clever way to get only the needed data? NULL values can be empty strings:

[{"Id":1,"Name":"John"}, {"Id":2,"Name":""}]

-Nikolai

Tobia

unread,
Sep 1, 2014, 1:04:48 PM9/1/14
to golan...@googlegroups.com
Greg,
that's quite useful.

I would have chosen slightly different names though, such as null.* for the nullable types (the ones that treat nulls as separate values) and zero.* for the ones that coalesce SQL null to the Go zero value. Or maybe use a single package and prefix Zero to the latter ones (null.ZeroInt, etc.)

Tobia

Greg Roseberry

unread,
Sep 1, 2014, 2:29:28 PM9/1/14
to golan...@googlegroups.com
Tobia,

Thank you for the suggestion. Calling the nullable types null.* and the zeroing ones zero.* makes a lot more sense. 
I have gone ahead and implemented your idea. This reverses the role of the old null package so it's a breaking change, but I upped the version on gopkg.in and the library has only been in the wild for about a day, so I hope it doesn't cause too much trouble. 
Reply all
Reply to author
Forward
0 new messages