将 Golang JSON 存储到 Postgresql
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25758138/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Storing Golang JSON into Postgresql
提问by moesef
I want to store a certain struct into my database that has a JSON field within it.
我想将某个结构存储到我的数据库中,其中包含一个 JSON 字段。
type Comp struct {
CompId int64 `db:"comp_id" json:"comp_id"`
StartDate time.Time `db:"start_date" json:"start_date"`
EndDate time.Time `db:"end_date" json:"end_date"`
WeeklySchedule json.RawMessage `db:"weekly_schedule" json:"weekly_schedule"`
}
The schema for the table is:
该表的架构是:
CREATE TABLE IF NOT EXISTS Tr.Comp(
comp_id SERIAL,
start_date timestamp NOT NULL,
end_date timestamp NOT NULL,
weekly_schedule json NOT NULL,
PRIMARY KEY (comp_id)
);
I am using sqlx and lib/pq driver in my project and the following will not execute. Instead it panics saying there is a nil pointer. DB is a global *sqlx.DB
struct
我在我的项目中使用 sqlx 和 lib/pq 驱动程序,以下将不会执行。相反,它恐慌地说有一个 nil 指针。DB 是一个全局*sqlx.DB
结构
tx := DB.MustBegin()
compFixture := Comp{
StartDate: time.Now(),
EndDate: time.Now().AddDate(1, 0, 0),
WeeklySchedule: json.RawMessage([]byte("{}")),
}
_, err = tx.NamedExec(
`INSERT INTO
Tr.Comp(comp_id,
start_date, end_date, weekly_schedule)
VALUES (DEFAULT,
:start_date, :end_date, :weekly_schedule)
RETURNING comp_id;`, compFixture)
if err != nil {
t.Fatal("Error creating fixture.", err)
}
When I remove weekly_schedule
from the schema and fixture things run fine. But for some reason, the when this field is included, the program panics. Any idea as to how I should define the weekly_schedule
field in both my DB schema and Go struct?
当我weekly_schedule
从架构和夹具中删除时,一切正常。但是由于某种原因,当包含此字段时,程序会出现混乱。关于我应该如何weekly_schedule
在我的数据库架构和 Go 结构中定义字段的任何想法?
采纳答案by jmaloney
回答by moesef
I don't know how clean of a solution this is but I ended up making my own data type JSONRaw
. The DB driver sees it as a []btye
but it can still be treated like a json.RawMessage in the Go Code.
我不知道这是一个多么干净的解决方案,但我最终制作了自己的数据类型JSONRaw
。DB 驱动程序将其视为一个,[]btye
但在 Go 代码中仍然可以将其视为 json.RawMessage。
type JSONRaw json.RawMessage
func (j JSONRaw) Value() (driver.Value, error) {
byteArr := []byte(j)
return driver.Value(byteArr), nil
}
func (j *JSONRaw) Scan(src interface{}) error {
asBytes, ok := src.([]byte)
if !ok {
return error(errors.New("Scan source was not []bytes"))
}
err := json.Unmarshal(asBytes, &j)
if err != nil {
return error(errors.New("Scan could not unmarshal to []string"))
}
return nil
}
func (m *JSONRaw) MarshalJSON() ([]byte, error) {
return *m, nil
}
func (m *JSONRaw) UnmarshalJSON(data []byte) error {
if m == nil {
return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
}
*m = append((*m)[0:0], data...)
return nil
}
This is copy paste reimplementation of MarshalJSON
and UnmarshalJSON
from the encoding/json
library.
这是复制粘贴重新实现MarshalJSON
,并UnmarshalJSON
从encoding/json
图书馆。
回答by ABri
from the go documentation:
从 go 文档:
json.RawMessage is a raw encoded JSON object. It implements Marshaler and Unmarshaler and can be used to delay JSON decoding or precompute a JSON encoding.
if you log.Printf("%#", colors) in the example provided at package json json.RawMessage you can see that after unmarshalling the json object 'Point'-member isn't unmarshalled but left in []byte format until the color-format is fixed and 'Point' is unmarshalled explicitly.
如果您在包 json json.RawMessage 中提供的示例中 log.Printf("%#", colors) 您可以看到在解组 json 对象 'Point'-member 后未解组而是以 []byte 格式保留,直到color-format 是固定的,'Point' 被明确地解组。
Did you try something like unmarshal WeeklySchedule before putting it into the DB?
在将它放入数据库之前,您是否尝试过解组 WeeklySchedule 之类的东西?