为了账号安全,请及时绑定邮箱和手机立即绑定

来自 Postgres 的 Golang 嵌套 JSON 结果

来自 Postgres 的 Golang 嵌套 JSON 结果

Go
ibeautiful 2021-12-20 19:34:15
我正在使用杜松子酒和gorpSQL:SELECT p.project_id, p.name, COALESCE(NULLIF(json_agg(a.*)::TEXT, '[null]'), '[]')::JSON AS apps FROM project p LEFT JOIN app a USING (project_id) WHERE p.user_id=19 GROUP BY p.project_id, p.name ORDER BY project_id结果: 高朗type Project struct {    ID        int64           `db:"project_id, primarykey, autoincrement" json:"id"`    UserID    int64           `db:"user_id" json:"user_id"`    Name      string          `db:"name" json:"name"`    Status    int             `db:"status" json:"status"`    UpdatedAt int64           `db:"updated_at" json:"updated_at"`    CreatedAt int64           `db:"created_at" json:"created_at"`    Apps      json.RawMessage `json:"apps"`}func GetProjects(userID int64, page string) []Project {    var projects []Project    var err error    _, err = db.GetDB().Select(&projects, "SELECT p.project_id, p.name, COALESCE(NULLIF(json_agg(a.*)::TEXT, '[null]'), '[]')::JSON AS apps FROM project p LEFT JOIN app a USING (project_id) WHERE p.user_id=$1 GROUP BY p.project_id, p.name ORDER BY project_id LIMIT 10 OFFSET $2", userID, page)    fmt.Println("err", err)    return projects}并使用以下方法返回结果: c.JSON(200, gin.H{"data": projects})如果只有一个项目,它会起作用但如果有多个项目,则会出现以下错误:错误: json: error calling MarshalJSON for type json.RawMessage: invalid character '"' after top-level value有什么建议?PS:我是 Golang 的新手
查看完整描述

2 回答

?
森栏

TA贡献1810条经验 获得超5个赞

您可以使用此站点http://json2struct.mervine.net/根据结果获得正确的结构。只需复制选择结果,并生成您体面的结构

或者您可以生成具有项目结构数组的新类型:

type Projects []Project


查看完整回答
反对 回复 2021-12-20
?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

我从这个答案中使用下面的这个解决方案使它工作


我不知道这是一个多么干净的解决方案,但我最终制作了自己的数据类型JSONRaw。DB 驱动程序将其视为 a,[]btye但json.RawMessage在 Go 代码中仍可将其视为 a 。


这是一个复制粘贴重新实现MarshalJSON,并UnmarshalJSON从编码/ JSON库。


//JSONRaw ...

type JSONRaw json.RawMessage


//Value ...

func (j JSONRaw) Value() (driver.Value, error) {

    byteArr := []byte(j)


    return driver.Value(byteArr), nil

}


//Scan ...

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

}


//MarshalJSON ...

func (j *JSONRaw) MarshalJSON() ([]byte, error) {

    return *j, nil

}


//UnmarshalJSON ...

func (j *JSONRaw) UnmarshalJSON(data []byte) error {

    if j == nil {

        return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")

    }

    *j = append((*j)[0:0], data...)

    return nil

}


//Project ....

type Project struct {

    ID        int64   `db:"project_id, primarykey, autoincrement" json:"id"`

    UserID    int64   `db:"user_id" json:"user_id"`

    Name      string  `db:"name" json:"name"`

    Status    int     `db:"status" json:"status"`

    UpdatedAt int64   `db:"updated_at" json:"updated_at"`

    CreatedAt int64   `db:"created_at" json:"created_at"`

    Apps      JSONRaw `json:"apps"`

}

//img1.sycdn.imooc.com//61c06a73000103b903450432.jpg

但我想知道除此之外是否还有干净的方法?

希望这也能帮助其他人。


查看完整回答
反对 回复 2021-12-20
  • 2 回答
  • 0 关注
  • 287 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号