JSON 来自 sqlite3 的字段
JSON fields from sqlite3
我在 sqlite3 集合中有一个 json 字段。我的架构如下所示:
CREATE Table Animals(
id int,
sounds json,
name string
)
我了解 go-sqlite 接口 does not support the json datatype explicitly。但是,我的 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 unmarshalling/parsing 而不是我的临时自定义打印。当我尝试时:
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 为 nulled [] 或 true NULL 的情况下使用 []uint8 字符串并进一步使其对这些字符串具有鲁棒性。
一些参考资料:
你的问题涉及到几个话题。但最简单的答案可能是:
不要使用关系数据库。
您似乎想要获取 objects/documents,因此使用本机支持此操作的存储机制将避免到处乱码的需要。 MongoDB、CouchDB 或其他一些 NoSQL 解决方案可能最适合您的需求。
不过话虽如此,你的具体问题还是有答案的。不过,将它们放在一起可以说是复杂而丑陋的东西。
- 你的
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")
}
}
- 扫描到一个结构
为此使用 sqlx。它允许您比标准库更容易地将整行扫描到一个结构中。它可以使用 db
标记将行与结构字段匹配。
- DB 和 JSON
的单一结构
您的结构中可以有多个标签:
type Animal struct {
id int `db:"id" json:"id"`
name sql.NullString `db:"name" json:"name"`
sounds []uint8 `db:"sounds" json:"sounds"`
}
我在 sqlite3 集合中有一个 json 字段。我的架构如下所示:
CREATE Table Animals(
id int,
sounds json,
name string
)
我了解 go-sqlite 接口 does not support the json datatype explicitly。但是,我的 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 unmarshalling/parsing 而不是我的临时自定义打印。当我尝试时:
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 为 nulled [] 或 true NULL 的情况下使用 []uint8 字符串并进一步使其对这些字符串具有鲁棒性。
一些参考资料:
你的问题涉及到几个话题。但最简单的答案可能是:
不要使用关系数据库。
您似乎想要获取 objects/documents,因此使用本机支持此操作的存储机制将避免到处乱码的需要。 MongoDB、CouchDB 或其他一些 NoSQL 解决方案可能最适合您的需求。
不过话虽如此,你的具体问题还是有答案的。不过,将它们放在一起可以说是复杂而丑陋的东西。
- 你的
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")
}
}
- 扫描到一个结构
为此使用 sqlx。它允许您比标准库更容易地将整行扫描到一个结构中。它可以使用 db
标记将行与结构字段匹配。
- DB 和 JSON 的单一结构
您的结构中可以有多个标签:
type Animal struct {
id int `db:"id" json:"id"`
name sql.NullString `db:"name" json:"name"`
sounds []uint8 `db:"sounds" json:"sounds"`
}