使用 jackc/pgx 将空字符串或 null 作为 null 插入 postgres
Inserting empty string or null into postgres as null using jackc/pgx
我正在使用外部 json API,它处理缺失值的方式不一致。有时 json 值显示为空字符串,有时显示为 null。例如...
案例 1:datedec
和 curr
都是空字符串。
{
"symbol": "XYZ",
"dateex": "2020-09-01",
"datedec": "",
"amount": "1.25",
"curr": "",
"freq": "annual"
}
案例 2:datedec
为空。 curr
已填充。
{
"symbol": "XYZ",
"dateex": "2020-09-01",
"datedec": null,
"amount": "1.25",
"curr": "USD",
"freq": "annual"
}
这是我用来表示股息的结构:
type Dividend struct {
symbol string `json:"symbol"`
dateex string `json:"dateex"`
datedec string `json:"datedec"`
amount string `json:"amount"`
curr string `json:"curr"`
freq string `json:"freq"`
}
我遇到的问题是如何将空字符串或 null 作为 NULL
插入到数据库中。我知道我可以使用 omitempty
json 标记,但是我将如何编写一个函数来处理我不知道会丢失的值?例如,这是我当前使用 jackc/pgx 包将股息插入 postgresql 的函数:
func InsertDividend(d Dividend) error {
sql := `INSERT INTO dividends
(symbol, dateex, datedec, amount, curr, freq)
VALUES (, , , , , )`
conn, err := pgx.Connect(ctx, "DATABASE_URL")
// handle error
defer conn.Close(ctx)
tx, err := conn.Begin()
// handle error
defer tx.Rollback(ctx)
_, err = tx.Exec(ctx, sql, d.symbol, d.dateex, d.datedec, d.amount, d.curr, d.freq)
// handle error
}
err = tx.Commit(ctx)
// handle error
return nil
}
如果缺少某个值(例如 datedec 或 curr),则此函数将出错。从这个post我看到了如何解决Case1。但是有没有更通用的方法来处理这两种情况(null 或空字符串)?
我一直在查看 database/sql 和 jackc/pgx 文档,但我还没有找到任何东西。我认为 sql.NullString 有潜力,但我不确定我应该怎么做。
如有任何建议,我们将不胜感激。谢谢!
在写入数据库时,您可以通过多种方式表示 NULL
。 sql.NullString
是一个选项,就像使用指针一样 (nil
= null
);选择实际上取决于您发现更容易理解的内容。罗斯·考克斯 commented:
There's no effective difference. We thought people might want to use NullString because it is so common and perhaps expresses the intent more clearly than *string. But either will work.
我怀疑在您的情况下使用指针是最简单的方法。例如,以下可能会满足您的需求:
type Dividend struct {
Symbol string `json:"symbol"`
Dateex string `json:"dateex"`
Datedec *string `json:"datedec"`
Amount string `json:"amount"`
Curr *string `json:"curr"`
Freq string `json:"freq"`
}
func unmarshal(in[]byte, div *Dividend) {
err := json.Unmarshal(in, div)
if err != nil {
panic(err)
}
// The below is not necessary unless if you want to ensure that blanks
// and missing values are both written to the database as NULL...
if div.Datedec != nil && len(*div.Datedec) == 0 {
div.Datedec = nil
}
if div.Curr != nil && len(*div.Curr) == 0 {
div.Curr = nil
}
}
试试看 in the playground.
在写入数据库时,您可以像现在一样使用 Dividend
结构; SQL 驱动程序会将 nil
写为 NULL
.
我正在使用外部 json API,它处理缺失值的方式不一致。有时 json 值显示为空字符串,有时显示为 null。例如...
案例 1:datedec
和 curr
都是空字符串。
{
"symbol": "XYZ",
"dateex": "2020-09-01",
"datedec": "",
"amount": "1.25",
"curr": "",
"freq": "annual"
}
案例 2:datedec
为空。 curr
已填充。
{
"symbol": "XYZ",
"dateex": "2020-09-01",
"datedec": null,
"amount": "1.25",
"curr": "USD",
"freq": "annual"
}
这是我用来表示股息的结构:
type Dividend struct {
symbol string `json:"symbol"`
dateex string `json:"dateex"`
datedec string `json:"datedec"`
amount string `json:"amount"`
curr string `json:"curr"`
freq string `json:"freq"`
}
我遇到的问题是如何将空字符串或 null 作为 NULL
插入到数据库中。我知道我可以使用 omitempty
json 标记,但是我将如何编写一个函数来处理我不知道会丢失的值?例如,这是我当前使用 jackc/pgx 包将股息插入 postgresql 的函数:
func InsertDividend(d Dividend) error {
sql := `INSERT INTO dividends
(symbol, dateex, datedec, amount, curr, freq)
VALUES (, , , , , )`
conn, err := pgx.Connect(ctx, "DATABASE_URL")
// handle error
defer conn.Close(ctx)
tx, err := conn.Begin()
// handle error
defer tx.Rollback(ctx)
_, err = tx.Exec(ctx, sql, d.symbol, d.dateex, d.datedec, d.amount, d.curr, d.freq)
// handle error
}
err = tx.Commit(ctx)
// handle error
return nil
}
如果缺少某个值(例如 datedec 或 curr),则此函数将出错。从这个post
我一直在查看 database/sql 和 jackc/pgx 文档,但我还没有找到任何东西。我认为 sql.NullString 有潜力,但我不确定我应该怎么做。
如有任何建议,我们将不胜感激。谢谢!
在写入数据库时,您可以通过多种方式表示 NULL
。 sql.NullString
是一个选项,就像使用指针一样 (nil
= null
);选择实际上取决于您发现更容易理解的内容。罗斯·考克斯 commented:
There's no effective difference. We thought people might want to use NullString because it is so common and perhaps expresses the intent more clearly than *string. But either will work.
我怀疑在您的情况下使用指针是最简单的方法。例如,以下可能会满足您的需求:
type Dividend struct {
Symbol string `json:"symbol"`
Dateex string `json:"dateex"`
Datedec *string `json:"datedec"`
Amount string `json:"amount"`
Curr *string `json:"curr"`
Freq string `json:"freq"`
}
func unmarshal(in[]byte, div *Dividend) {
err := json.Unmarshal(in, div)
if err != nil {
panic(err)
}
// The below is not necessary unless if you want to ensure that blanks
// and missing values are both written to the database as NULL...
if div.Datedec != nil && len(*div.Datedec) == 0 {
div.Datedec = nil
}
if div.Curr != nil && len(*div.Curr) == 0 {
div.Curr = nil
}
}
试试看 in the playground.
在写入数据库时,您可以像现在一样使用 Dividend
结构; SQL 驱动程序会将 nil
写为 NULL
.