golang的sqlite驱动不使用cgo实现 更换gorm默认的SQLite驱动

golang的sqlite驱动不使用cgo实现 更换gorm默认的SQLite驱动

最近在开发一个边缘物联网程序时使用Golang开发,用到GORM来操作SQLite数据库,GORM默认使用gorm.io/driver/sqlite这个库作为SQLite驱动,该库用CGO实现,在使用过程中遇到一些问题,编译好二进制程序放到资源受限的设备中运行,报错如下;最后更换第三方SQLite驱动解决。

github.com/mattn/go-sqlite3 这个库现在在 go 项目当中,引用最多,应用最广;俨然成为这一方面的标准,但有一个最大的问题就是,这是一个 C 语言实现的库,如果要应用这个库,那么你的环境就需要解决这个 CGO 依赖。

报错如下,正是因为GORM官方SQLite驱动使用CGO实现,因此我在使用过程中遇到以下错误:

shell 复制代码
[error] failed to initialize database, got error Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub panic: Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub

大致意思是GORM SQLite驱动使用了CGO实现,需要在CGO环境下才能工作。

那么解决方法也很简单,只需要修改CGO_ENABLED这个环境变量启用CGO支持即可:

shell 复制代码
go env -w CGO_ENABLED=1

启用CGO后,编译的是动态链库的二进制文件,那么你一旦更换平台,比如将程序放到Windows下运行,可能因为缺少相关的一些动态链库(比如:SQLite)从而无法运行,为了保持编译的二进制文件能够无动态依赖的情况下正常运行,因此不得不考虑静态编译,所以就和GORM SQLite驱动产生了冲突。

很多瘦小设备,弱设备里的系统,没有相关依赖库和驱动,也很难安装相关的驱动,此时不得不考虑使用不依赖任何三方的驱动情况下运行程序。

解决方案-更换GORM默认的SQLite驱动

在GORM官方的Issues发现也有人反馈此类问题,于是顺藤摸瓜,找到了github.com/glebarez/sqlite这个库,该库使用纯go实现,不依赖CGO,地址是:https://github.com/glebarez/sqlite

使用如下驱动

golang 复制代码
import (
    "fmt"
	_ "github.com/glebarez/sqlite"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/sqlite"
)

const (
	dbDriverName = "sqlite"
	dbName       = "iot.db"
)

var SqliteDb *gorm.DB

func SqliteInit() {
	var err error
	SqliteDb, err = gorm.Open(dbDriverName, "./"+dbName)
	if err != nil {
		fmt.Printf("connect DB failed, err:%v\n", err)
		return
	}
	fmt.Println("connect DB success")
	// 打印 SQL 语句
	SqliteDb.LogMode(true)

	// 空闲状态下的最大连接数,默认的最大空闲连接数为2
	SqliteDb.DB().SetMaxIdleConns(10)
	// 最大打开连接数, 默认值为0(无限制)
	SqliteDb.DB().SetMaxOpenConns(50)
	// 不要复数表名
	SqliteDb.SingularTable(true)

	// 自动迁移模型(创建表)
	//SqliteDb.AutoMigrate()
}

func SqliteClose() {
	//关闭
	SqliteDb.Close()
}

这样就可以在不依赖CGO的情况下编译出静态二进制文件,从而解决跨平台依赖动态链库的问题。

代价

glebarez/sqlite性能不及官方驱动,但牺牲少部分性能来换取方便个人觉得还是值得的,如果没有跨平台需求,使用官方默认驱动即可

静态编译打包后的文件体积明显增加

参考链接:

https://blog.xiaoz.org/archives/18195

https://wiki.eryajf.net/pages/74da0a/#前言

https://yoby123.cn/2021/06/15/20210615-sqlite.html

相关推荐
007php0073 小时前
Go语言zero项目部署后启动失败问题分析与解决
java·服务器·网络·python·golang·php·ai编程
MClink10 小时前
Go怎么做性能优化工具篇之pprof
开发语言·性能优化·golang
一行玩python11 小时前
sqlite3,一个轻量级的 C++ 数据库库!
开发语言·数据库·c++·oracle·sqlite
m0_7482546612 小时前
go官方日志库带色彩格式化
android·开发语言·golang
yoyo勰13 小时前
sqlite3
c语言·sqlite
搬码后生仔14 小时前
SQLite 是一个轻量级的嵌入式数据库,不需要安装服务器,直接使用文件即可。
数据库·sqlite
码农君莫笑14 小时前
Blazor项目中使用EF读写 SQLite 数据库
linux·数据库·sqlite·c#·.netcore·人机交互·visual studio
江上挽风&sty15 小时前
【Django篇】--动手实践Django基础知识
数据库·django·sqlite
Algorithm157615 小时前
云原生相关的 Go 语言工程师技术路线(含博客网址导航)
开发语言·云原生·golang
Narutolxy16 小时前
深入探讨 Go 中的高级表单验证与翻译:Gin 与 Validator 的实践之道20241223
开发语言·golang·gin