Consider that I have a table t1 in my postgres database like so:
CREATE TABLE t1 (
id SERIAL PRIMARY KEY,
col_2 TEXT DEFAULT "foo",
col_3 TEXT NOT NULL DEFAULT "bar",
...
col_X INTEGER NOT NULL DEFAULT 42
);
And that I receive a JSON object obj
which I unmarshall in a struct ObjStrct
:
type ObjStrct {
id *int32 `json:id,omitempty`,
s1 *string `json:s1,omitempty`,
s2 *string `json:s2,omitempty`,
...
nr *int32 `json:nr,omitempty`
}
var obj ObjStrct
err := json.NewDecoder(request.Body).Decode(&obj)
// error handling has been done
Now I want to insert that object into my database:
// connection to db established
row := db.QueryRow(
`INSERT INTO
t1 (col_1, col_2, ..., col_X)
VALUES
($1, $2, ..., $X)
RETURNING
id;`,
*obj.s1, *obj.s2, ..., *obj.nr)
The issue is: All those obj.*
-values could be nil
in which case the sql DEFAULT value should be used.
My question is: How do I achieve this?
- datatypes from the sql package (sql.Null<TYPE>) do not support the DEFAULT keyword afaik.
- Functions like
func defaultOnNil(v *int32) any { ... }
returning "DEFAULT" whenv
is nil andv
instead do not work. See this related post
2
Answers
To use the
DEFAULT
value of a column anINSERT
should exclude the column while inserting.This means, you’ll need to process the JSON object, find out which values are nil, and remove them from the query.
For example, if the JSON object has
s2
as nil, thencol2
should be removed from your query; it should be modified as:This is easily done by any ORM that implements Dynamic SQL functionality.
Another option is send the keyword DEFAULT instead of the value parsed from the json. So:
You do not use quotes around DEFAULT, in this usage it is a keyword.