sql - 如何处理可为空的Postgres JSONB数据并将其解析为JSON

标签 sql json postgresql go

数据库记录

---------------------------------------------------------
| id | test_json                                        |
---------------------------------------------------------
| 1  | NULL                                             |
---------------------------------------------------------
| 2  | { "firstName": "Hello", "lastName": "World" }    |
---------------------------------------------------------

我在postgres中有JSONB列,可以为NULL。我想用golang读取此记录数据库并将其发送给客户端。

我在SQL扫描中遇到以下错误:
sql: Scan error on column index 2, name "test_json": unsupported Scan, storing driver.Value type []uint8 into type *models.TestJSONNullable
exit status 1

我正在使用echo Web服务器。
package models

import (
    "fmt"
    "github.com/lib/pq"
    "encoding/json"
)

type TestJson struct {
    First_name *string `json:"firstName"`
    Last_name *string `json:"lastName"`
}

type TestJSONNullable struct {
  Valid bool
}

func (i *TestJSONNullable) UnmarshalJSON(data []byte) error {
  if string(data) == "null" {
    i.Valid = false
    return nil
  }

  // The key isn't set to null
  var temp *TestJson
  if err := json.Unmarshal(data, &temp); err != nil {
    return err
  }
  i.Valid = true
  return nil
}

type Test01 struct {
    Id string `json:"id"`
    Test_json *TestJSONNullable `json:"testJson"`
}


func (db *DB) TestRecords () ([]*Test01, error)  {
    rows, err := db.Query("SELECT id, test_json FROM table_1 where success = true")

    if err != nil {
        log.Fatal(err)
        return nil, err
    }

    defer rows.Close()

    recs := []*Test01{}

    for rows.Next() {
        r := new(Test01)

        err := rows.Scan(&r.Id, &r.Test_json)

        if err != nil {
            log.Fatal(err)
            return nil, err
        }

        recs = append(recs, r)
    }

    if err = rows.Err(); err != nil {
        log.Fatal(err)
        return nil, err
    }

    return recs, nil
}

最佳答案

经过研究后,我找到了解决方案。

type TestJSONMap map[string]interface{}

func (t TestJSONMap) Value() (driver.Value, error) {
    j, err := json.Marshal(t)
    return j, err
}

func (p *TestJSONMap) Scan(val interface{}) error {
    value, ok := val.([]byte)
    if !ok {
        return errors.New("Type assertion .([]byte) failed.")
    }

    var i interface{}
    err := json.Unmarshal(value, &i)
    if err != nil {
        return err
    }

    *p, ok = i.(map[string]interface{})
    if !ok {
        return errors.New("Type assertion .(map[string]interface{}) failed.")
    }

    return nil
}

type Test01 struct {
    Id string `json:"id"`
    Test_json *TestJSONMap `json:"testJson"`
}

得到了https://coussej.github.io/2016/02/16/Handling-JSONB-in-Go-Structs/的帮助

关于sql - 如何处理可为空的Postgres JSONB数据并将其解析为JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59244393/

相关文章:

sql - 选择一列 DISTINCT SQL

python - 如何制作多列,每列具有不同的行

python - 如何创建连接、执行和断开连接的函数

postgresql - PostgreSQL 可以加入存储过程吗?

mysql - 在这种情况下我应该使用派生表吗?

sql - vi编写的Hive文本表

mysql join 限制为 1

ios - 如何使用 Alamofire 4 在 Swift 3 中发送带有参数和主体的 JSON 数据的 POST 请求?

java - 当 JSON 不包含某个字段时,Gson 会将其设置为 null 吗?

sql - PostgreSQL 从日期类型获取年份作为整数