go - 如何在 Go 二进制文件中捆绑 SQLite 数据库?
问题描述
我尝试使用 go-bindata 和 packr,但这些包没有显示如何将 SQLite 数据库文件打包到二进制文件中。
我不需要以任何方式更新数据库,我只想在启动时从中读取数据。
如何在 Go 二进制文件中嵌入 SQLite 数据库文件?
解决方案
SQLite 驱动程序不能从内存中读取数据库文件(例如从字节片)。但是您可以将数据写入临时文件,然后打开它:
//go:generate go run gen.go
package main
import (
"database/sql"
"fmt"
"io/ioutil"
"log"
"os"
_ "github.com/mattn/go-sqlite3"
)
func main() {
// Create temporary file for database.
tmpDB, err := ioutil.TempFile("", "db*.sqlite3")
if err != nil {
log.Fatal(err)
}
// Remove this file after on exit.
defer func() {
err := os.Remove(tmpDB.Name())
if err != nil {
log.Print(err)
}
}()
// Write database to file.
_, err = tmpDB.Write(sqlDB)
if err != nil {
log.Print(err)
}
err = tmpDB.Close()
if err != nil {
log.Print(err)
}
// Open DB.
db, err := sql.Open("sqlite3", tmpDB.Name()+"?mode=ro")
if err != nil {
log.Fatal(err)
}
// Make sure it's loaded correct.
rows, err := db.Query("select * from test")
if err != nil {
log.Fatal(err)
}
for rows.Next() {
var c string
err := rows.Scan(&c)
if err != nil {
log.Fatal(err)
}
fmt.Println(c)
}
}
您可以使用以下内容将数据库写入db.go
:
// +build generate
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
"strings"
)
func main() {
// Read source database file.
d, err := ioutil.ReadFile("source.sqlite3")
if err != nil {
log.Fatal(err)
}
fp, err := os.Create("db.go")
if err != nil {
log.Fatal(err)
}
_, err = fmt.Fprintf(fp, "// Code generated by gen.go; DO NOT EDIT.\n\n"+
"package main\n\n"+
"var sqlDB = %s\n", asbyte(d))
if err != nil {
log.Fatal(err)
}
}
// Write any data as byte array.
func asbyte(s []byte) string {
var b strings.Builder
for i, c := range s {
if i%19 == 0 {
b.WriteString("\n\t\t")
}
b.WriteString(fmt.Sprintf("%#x, ", c))
}
return "[]byte{" + b.String() + "}"
}
如果您愿意,您也可以使用 go-bindata 或 packr,但我并没有真正看到优势。
另一种方法是使用内存数据库,这可能会更快,具体取决于您想要做什么。
- 将你想要的 SQL 模式和行作为字符串嵌入到你的 Go 二进制文件中。
- 当你的程序启动时打开一个新的内存数据库(
sql.Open("sqlite3",
:memory:`)并创建模式并插入行。
这种方法没有磁盘访问,因此查询它可能会更快一些,代价是启动时间较慢(肯定是基准!)
推荐阅读
- google-chrome - 添加 COOP COEP HTTP 标头会导致第三方脚本停止在 Chrome 上运行
- django - Django 管理员登录页面搞砸了。(可能在 git pull 之后?我不确定)
- python - 正则表达式从一组 JSON 中查找数值数据
- python - 将 KerasTensor 对象转换为 numpy 数组以在 Callback 中可视化预测
- javascript - 这是 O(n^2) 运行时还是 O(n)?
- reactjs - 我弹出了我的 React 应用程序并将其配置为使用 css 模块进行样式设置,但我在 npm start 上不断收到此错误
- html - CSS 部分重叠且图像不居中
- python - python sklearn:抑制 ConvergenceWarning n_job=-1
- c++ - 我们可以在 getopt_long 函数中使用动态数组 data() 作为 longopts 参数吗?
- node.js - 获取失败如何调查?