我想将某个结构存储到我的数据库中,其中包含一个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"`
}
该表的架构是:
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)
);
我在我的项目中使用sqlx和lib / pq驱动程序,以下内容将不会执行。相反,恐慌说有一个零指针。 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)
}
当我从架构中移除weekly_schedule
并且装置时运行正常。但由于某种原因,当该字段被包括在内时,程序会出现恐慌。有关如何在我的数据库模式和Go结构中定义weekly_schedule
字段的任何想法吗?
答案 0 :(得分:9)
sqlx在JSONText
中的github.com/jmoiron/sqlx/types
类型可以满足您的需要
doc用于JSONText
答案 1 :(得分:2)
我不知道解决方案有多干净,但我最终创建了自己的数据类型JSONRaw
。数据库驱动程序将其视为[]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
}
这是来自MarshalJSON
库的UnmarshalJSON
和encoding/json
的复制粘贴重新实现。
答案 2 :(得分:0)
来自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.
如果你在包json json.RawMessage中提供的示例中log.Printf("%#",colors),你可以看到解组后的json对象' Point' - 成员没有被编组,但以[]字节格式保留,直到颜色格式被修复并且' Point'是明确的解组。
在将它放入数据库之前,您是否尝试过像解组WeeklySchedule这样的内容?