Hello all, I have alot of experience with relational databases in other languages (php, c#, java, etc) but whenever i try to use the sql package in go it feels superrrr clunky.... how do you guys deal with nulls? (i like using deletedAt nullable date time columns) I hate having to use things like sql.NullString and I especially hate having to use mysql.NullTime because it kills my portability. Right now Im leaning twords using https://github.com/boltdb/bolt but I like relational DB's....
It just feels clunky...
edit: preliminary tests show that you can use string/date pointers rather then sql.NullString, I need to explore this further....
thanks /u/TheMerovius
评论:
twek:
BoTuLoX:Im going to give this a try i think...
twek:It adds some nifty functionality. To deal with nullable time I just make it a pointer.
Growlizing:yeah thats where im getting too... I really dislike those nullable structs pointers seem nicer
twek:I also found it extremely clunky. Something like gorp did help me though, which I've now started using for rdbms.
Growlizing:glad im not the only one! I looked at gorp but gorm seemed more supported and it wasnt very unclunky either
twek:Yeah, well, I'm too scarred from java and ruby world I think to ever use a full ORM again :(
TheMerovius:I know that feeling.
In java i roll my own DAO's using springs NamedJDBCTemplate
its the only spring i can stomach
twek:a) If your data can't be NULL, use
string
. If your data can be NULL, you'll have to usesql.NullString
or something like it anyway. I don't see, how that affects your "portability"? (I think… maybe? You can also use a pointer. Not sure)b) If you don't want to put
sql.NullString
like things into your struct, you can scan into an anonymous struct and then manually copy the fields over with whatever logic you like.But I find it difficult seeing your problem. I don't see how PHP specifically makes this easier?
TheMerovius:the portability problem comes from the fact that the standard sql package does not contain a sql.NullDate so you have to use mysql.NullDate which locks you to the mysql package (not sure if theres an alternative in sqlite etc packages) I havnt tried a date pointer... Ill have to try that.
I thought about the anonymous struct thing and its probably my best bet (because yes i dont like sql.NullString in my struct if i can help it)
Im not having any PROBLEMS (i.e the code works)
but the development of said code feels clunky is all... and when that happens I like to think theres a better way.
twek:the portability problem comes from the fact that the standard sql package does not contain a sql.NullDate so you have to use mysql.NullDate which locks you to the mysql package (not sure if theres an alternative in sqlite etc packages) I havnt tried a date pointer... Ill have to try that.
You can use a mysql.NullDate with any other sql driver too. Or just copy-paste the type into your own code and use that (then you don't need to import the mysql-driver.
Also, in my experience, every SQL database has a different feature-set (in particular, dates are AFAIK one of the things that differ wildly) so you very probably are not portable between databases anyway. :)
and when that happens I like to think theres a better way.
I like sqlx whenever I need SQL stuff :) It gives a good tradeoff between simplicity and power, IMHO.
[edit] To elaborate on portability: For example, how you give placeholder in prepared statements varies, sometimes you need positional arguments, sometimes you need '?' (I think mysql does that) and sometimes both work.
twek:I have not tried sqlx yet but just the fact that I can use pointers in my structs rather then sql.Null** is already a great win, the alternative is to write a nice search feature for boltdb. Which would give me an excuse to brush up on cool stuff like breadth first search and graphs....
TheMerovius:And php/java etc make this easier by allowing nullable primitives
twek:
sql.NullString
is a "nullable primitive". It gives you precisely the same semantics, just slightly different syntax.
TheMerovius:Well its a struct not a primitive
WellAdjustedOutlaw:As I said, it gives you precisely the same semantics. You just have to write
if !nullString.Valid()
instead ofif (!defined null_string)
, or however you check for undefinednes in PHP and usenullString.Value()
, instead ofnull_string
. You are splitting hairs.
twek:A word of warning. If you think a key/value store is going to help you when you need an rdbms, you're in for a world of hurt. Also, if you think using and learning a new db is going to be a cakewalk vs the probably years of experience you have with something like MySQL, you're going to have a very bumpy ride. Just my $0.02
I found the Go approach to databases a bit wonky until I understood Go more. Not that I'm good now, I just seem to understand other Golang developers' intentions more readily now. /shrug
ptman:Luckily I also have years of experience with writing various btree key value stores, for my application to work I would just have to write an efficient search for boltdb I was thinking a dictionary with a graph like component... iono Ill probably just use mysql and pointers
Not all Go ORMs can handle pointers to time.Time: https://github.com/astaxie/beego/issues/1019
