2

我在 sqlite3 集合中有一个 json 字段。我的架构看起来像:

CREATE Table Animals(
  id int,
  sounds json,
  name string
)

我了解 go-sqlite 接口不明确支持 json 数据类型。但是,我的 json 非常简单,因为所有字段都是 json 数组,例如;

["bark", "woof", "growl"]
["meow", "hiss", "growl"]

所以完整的记录可能是:

id   sounds                      name
1    ["bark", "woof", "growl"]   Fido
2    ["meow", "hiss", "growl"]   Rufus

使用包:

_ "github.com/mattn/go-sqlite3"

我能够提取我的 json 字段

var id sql.NullInt64
var name sql.NullString
var sounds []uint8

err := db.QueryRow("SELECT id,name,sounds FROM Animals WHERE id = ?;", 1).Scan(&id, &name, &sounds)

fmt.Println(strconv.Itoa(id) + "|" + name + "|" + strings.Join(sounds, "+"))

// does print correctly:
1|Fido|bark+wood+growl

也就是说,似乎 sqlite3 json 被存储在一个 unicode 字符串(?)中作为一系列......字节?......我可以使用 String 模块转换为字符串。我还对“+”连接操作感兴趣,所以我可以为下游的另一个应用程序制作一个查询+字符串+查找+东西。

但是,我真的很想将这一切都捆绑在 JSON 中,并利用 JSON 解组/解析而不是我的临时自定义打印。当我尝试:

type Animal struct {
    id int                   `json:"id"`
    name sql.NullString      `json:"name"`
    sounds []uint8           `json:"sounds"`
}

var a Animal

err := db.QueryRow("SELECT id,name,sounds FROM Animals WHERE id = ?;", 1).Scan(&a.id, &a.name, &a.sounds
)

它打印一个真正的整数数组。如何在启用 json 的类型定义中嵌入 strings.Join(sounds []uint8) 声明 + 函数转换组合?

此外,我不清楚如何在 json 为 null [] 或 true NULL 的情况下使用 []uint8 字符串,并进一步使其对这些具有鲁棒性。

一些参考:

4

1 回答 1

0

你的问题引出了几个话题。但对所有这些问题最简单的答案可能是:

不要使用关系数据库。

您似乎想要获取对象/文档,因此使用本机支持此功能的存储机制将防止到处需要杂乱无章的东西。MongoDB、CouchDB 或其他一些 NoSQL 解决方案可能适合您的需求。

但是话虽如此,您的具体问题都有答案。不过,它们放在一起可以说是复杂而丑陋的东西。

  1. 你的sounds类型。

创建一个自定义类型,该类型实现sql.Scanner接口,并为您解组 JSON 值:

    type Sounds []string

    func (s *Sounds) Scan(src interface{}) error {
        switch t := src.(type) {
        case []byte:
            return json.Unmarshal(t, &s)
        default:
            return errors.New("Invalid type")
        }
    }
  1. 扫描到结构体

为此使用sqlx。它允许您比标准库更容易地将整行扫描到结构中。它可以使用db标签将行与结构字段匹配。

  1. DB 和 JSON 的单一结构

您的结构中可以有多个标签:

    type Animal struct {
        id int                   `db:"id" json:"id"`
        name sql.NullString      `db:"name" json:"name"`
        sounds []uint8           `db:"sounds" json:"sounds"`
    }
于 2018-01-31T07:46:29.973 回答