如何在Go二进制文件中捆绑SQLite数据库?

TangMonk :

我尝试使用go-bindata和packr,但是这些软件包没有显示如何将SQLite数据库文件打包为二进制文件。

我不需要以任何方式更新数据库,我只想在启动时从中读取数据。

如何将SQLite数据库文件嵌入Go二进制文件中?

马丁·图尔诺伊(Martin Tournoij):

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,但是我看不出有什么优势。


另一种方法是使用内存数据库,这可能会更快,具体取决于您要执行的操作。

  1. 将SQL模式和所需的行作为字符串嵌入到Go二进制文件中。
  2. 程序启动时(sql.Open("sqlite3",:memory:`),打开一个新的内存数据库,并创建架构并插入行。

此方法无法访问磁盘,因此以较慢的启动时间为代价,查询它可能会快一些(请确保使用基准测试!)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在Go中读取二进制文件

如何将二进制文件存储在sql数据库中?

ASP.Core上传文件:如何在数据库表中存储二进制文件,使用Dapper插入数据

数据库设计中的二进制关系与非二进制关系

如何在Angular 5中解析和播放数据库中的Blob /二进制数据

如何在ASP.NET中使用C#从数据库中检索二进制图像

NET控制中从数据库到.rtf的LabVIEW二进制文件

PHP-如何从二进制字符串到数据库中的Blob?

我如何从数据库中检索以二进制格式存储的图像

如何在Ubuntu中编辑文件的二进制或十六进制数据?

如何在Go中打开图像以获取黑白像素的二进制数据?

如何在Go中读取打包的二进制数据?

传递参数时如何在调试器中运行Go二进制文件?

如何在Go中构建发行版二进制文件?

如何在pyspark中读取二进制数据

如何在Julia中读取二进制文件?

如何在Android中编辑二进制文件?

如何在C++中以相反的顺序读取二进制数据文件

Lightroom SQLite数据库二进制XMP格式

如何使用jQuery渲染以二进制数据形式保存在数据库中的PDF?

将IPv6转换为二进制文件后将其存储到数据库中

如何通过使用SQL Server Management Studio将Excel文件作为二进制类型导入数据库表中

如何在一个二进制文件中连接一百万个二进制文件?

将图片显示为数据库中的二进制数据

为了安全起见,将二进制数据存储在数据库中

如何从数据库中定义以二进制格式存储为div背景图像的图像?

尝试将图像作为二进制插入到数据库中

无法将二进制图像提交到 Laravel 中的数据库

如何使用另一个数据库中的变量在现有数据库中创建新的二进制列?