将 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 01:36:49  来源:igfitidea点击:

Storing Golang JSON into Postgresql

sqljsonpostgresqlstructgo

提问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.DBstruct

我在我的项目中使用 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_schedulefrom 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_schedulefield in both my DB schema and Go struct?

当我weekly_schedule从架构和夹具中删除时,一切正常。但是由于某种原因,当包含此字段时,程序会出现混乱。关于我应该如何weekly_schedule在我的数据库架构和 Go 结构中定义字段的任何想法?

采纳答案by jmaloney

sqlx has a type JSONTextin github.com/jmtheitroadon/sqlx/typesthat will do what you need

SQLX有一个类型JSONTextgithub.com/jmtheitroadon/sqlx/types,会做你需要什么

docfor JSONText

JSONText文档

回答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 []btyebut 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 MarshalJSONand UnmarshalJSONfrom the encoding/jsonlibrary.

这是复制粘贴重新实现MarshalJSON,并UnmarshalJSONencoding/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 之类的东西?