更换GORM默认SQLite驱动出现的问题解决分析
GORM简介
GORM 是 Go 语言中最受欢迎的 ORM 库之一,它提供了强大的功能和简洁的 API,让数据库操作变得更加简单和易维护。本文将详细介绍 GORM 的常见用法,包括数据库连接、模型定义、CRUD、事务管理等方面,帮助大家快速上手使用 GORM 进行 Web 后端开发。
安装
通过如下命令安装 GORM:
$ go get -u gorm.io/gorm
你也许见过使用 go get -u github.com/jinzhu/gorm
命令来安装 GORM,这个是老版本 v1,现已过时,不建议使用。新版本 v2 已经迁移至 github.com/go-gorm/gorm
仓库下。
快速开始GORM使用
如下示例代码带你快速上手 GORM 的使用:
package main import ( "gorm.io/driver/sqlite" "gorm.io/gorm" ) // Product 定义结构体用来映射数据库表 type Product struct { gorm.Model Code string Price uint } func main() { // 建立数据库连接 db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) if err != nil { panic("failed to connect database") } // 迁移表结构 db.AutoMigrate(&Product{}) // 增加数据 db.Create(&Product{Code: "D42", Price: 100}) // 查找数据 var product Product db.First(&product, 1) // find product with integer primary key db.First(&product, "code = ?", "D42") // find product with code D42 // 更新数据 - update product's price to 200 db.Model(&product).Update("Price", 200) // 更新数据 - update multiple fields db.Model(&product).Updates(Product{Price: 200, Code: "F42"}) // non-zero fields db.Model(&product).Updates(map[string]interface{}{"Price": 200, "Code": "F42"}) // 删除数据 - delete product db.Delete(&product, 1) }
提示:这里使用了 SQLite
数据库驱动,需要通过 go get -u gorm.io/driver/sqlite
命令安装。
将以上代码保存在 main.go
中并执行。
$ go run main.go
执行完成后,我们将在当前目录下得到 test.db
SQLite 数据库文件。
① 进入 SQLite 命令行。
② 查看已存在的数据库表。
③ 设置稍后查询表数据时的输出模式为按列左对齐。
④ 查询表中存在的数据。
有过使用 ORM 框架经验的同学,以上代码即使我不进行讲解也能看懂个大概。
这段示例代码基本能够概括 GORM 框架使用套路:
- 定义结构体映射表结构:
Product
结构体在 GORM 中称作「模型」,一个模型对应一张数据库表,一个结构体实例对象对应一条数据库表记录。 - 连接数据库:GORM 使用
gorm.Open
方法与数据库建立连接,连接建立好后,才能对数据库进行 CRUD 操作。 - 自动迁移表结构:调用
db.AutoMigrate
方法能够自动完成在数据库中创建Product
结构体所映射的数据库表,并且,当Product
结构体字段有变更,再次执行迁移代码,GORM 会自动对表结构进行调整,非常方便。不过,我不推荐在生产环境项目中使用此功能。因为数据库表操作都是高风险操作,一定要经过多人 Review 并审核通过,才能执行操作。GORM 自动迁移功能虽然理论上不会出现问题,但线上操作谨慎为妙,个人认为只有在小项目或数据不那么重要的项目中使用比较合适。 - CRUD 操作:迁移好数据库后,就有了数据库表,可以进行 CRUD 操作了。
更换第三方SQLite驱动解决
最近在开发一个程序时用到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
性能不及官方驱动,但牺牲少部分性能来换取方便个人觉得还是值得的,如果没有跨平台需求,使用官方默认驱动即可- 静态编译打包后的文件体积明显增加
以上就是更换GORM默认SQLite驱动出现的问题解决分析的详细内容,更多关于更换GORM默认SQLite驱动的资料请关注脚本之家其它相关文章!
相关文章
GO将mysql 中 decimal 数据类型映射到 protobuf的操作方法
这篇文章主要介绍了go如何优雅地将 mysql 中 decimal 数据类型映射到 protobuf,本文主要展示一下在 protobuf中 float与double的一个区别,结合实例代码给大家介绍的非常详细,需要的朋友可以参考下2022-09-09Golang 实现 Redis系列(六)如何实现 pipeline 模式的 redis 客户端
pipeline 模式的 redis 客户端需要有两个后台协程负责 tcp 通信,调用方通过 channel 向后台协程发送指令,并阻塞等待直到收到响应,本文是使用 golang 实现 redis 系列的第六篇, 将介绍如何实现一个 Pipeline 模式的 Redis 客户端。2021-07-07
最新评论