当前位置: 首页 > 软件编程 > Golang > 更换GORM默认的SQLite驱动

更换GORM默认的SQLite驱动

发布于:2022-12-28 Golang 5条评论 11,947 views
本站提供Linux服务器运维,自动化脚本编写等服务,如有需要请联系博主微信:xiaozme

最近在开发一个程序时用到GORM来操作SQLite数据库,GORM默认使用gorm.io/driver/sqlite这个库作为SQLite驱动,该库用CGO实现,在使用过程中遇到一些问题,最后更换第三方SQLite驱动解决。

问题

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

[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支持即可:

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

于是将官方的驱动:

import (
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

更换为:

import (
    "github.com/glebarez/sqlite"
    "gorm.io/gorm"
)

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

代价

  • glebarez/sqlite性能不及官方驱动,但牺牲少部分性能来换取方便个人觉得还是值得的,如果没有跨平台需求,使用官方默认驱动即可
  • 静态编译打包后的文件体积明显增加

标签: , ,

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注


已有5条评论


  1. 今天刚遇到这个问题,程序移植性在这里收到阻碍。需要将程序移植到一个数通产品去,数通产品的 glibc 库是 2.12.2,这都是10多年前的东西了。使用 gorm 官方的 sqlite3 驱动在这里就移植不了。这个替代库也查到了,只不过这个 go1.18 对于我们来讲又有点高版本了,我们现在还在使用 go1.15…看来得申请一下使用高版本的 go 才能解决这个问题了

    1. 我都没注意这个库对Golang版本的要求,我用的Golang版本一般都比较新。如果是生产环境的话还是要谨慎一点。

  2. 如果是docker构建出现这个问题,是因为构建容器和运行容器库不一样,例如运行容器是alpine,构建容器应该用golang:1.18-alpine而不是golang:1.18

    1. 我程序是跨平台的,linux下没问题,但是在windows平台上遇到这个问题,windows下cgo很麻烦,所以就换驱动了。

      1. 我与你的恰恰相反,在window 编译exe 能运行。 用工具编译成 linux64 运行不起。