更换GORM默认SQLite驱动出现的问题解决分析

 更新时间:2024年02月01日 14:12:12   作者:sample SK 刹客网络科技资讯  
这篇文章主要为大家介绍了更换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语言题解LeetCode268丢失的数字示例详解

    Go语言题解LeetCode268丢失的数字示例详解

    这篇文章主要为大家介绍了Go语言题解LeetCode268丢失的数字示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • Golang Mutex互斥锁深入理解

    Golang Mutex互斥锁深入理解

    这篇文章主要为大家介绍了Golang Mutex互斥锁深入理解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • 详解如何使用Go模块进行依赖管理

    详解如何使用Go模块进行依赖管理

    本文将介绍Go语言中的模块(module)概念,以及如何使用Go模块进行依赖管理,我们会探讨模块的基本概念、使用方法、配置和依赖关系管理等方面的内容,需要的朋友可以参考下
    2023-10-10
  • 详解golang consul-grpc 服务注册与发现

    详解golang consul-grpc 服务注册与发现

    这篇文章主要介绍了详解golang consul-grpc 服务注册与发现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • Go语言中定时任务库Cron使用方法介绍

    Go语言中定时任务库Cron使用方法介绍

    cron的意思计划任务,说白了就是定时任务。我和系统约个时间,你在几点几分几秒或者每隔几分钟跑一个任务(job),今天通过本文给大家介绍下Go语言中定时任务库Cron使用方法,感兴趣的朋友一起看看吧
    2022-03-03
  • 利用ChatGPT编写一个Golang图像压缩函数

    利用ChatGPT编写一个Golang图像压缩函数

    这篇文章主要为大家详细介绍了如何利用ChatGPT帮我们写了一个Golang图像压缩函数,文中的示例代码简洁易懂,感兴趣的小伙伴可以尝试一下
    2023-04-04
  • 详解go语言中type关键词的几种使用

    详解go语言中type关键词的几种使用

    这篇文章主要介绍了详解go语言中type的几种使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • Golang二进制反汇编问题

    Golang二进制反汇编问题

    这篇文章主要介绍了Golang二进制反汇编问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Hugo Config模块构建实现源码剖析

    Hugo Config模块构建实现源码剖析

    这篇文章主要为大家介绍了Hugo Config模块构建实现源码剖析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • Go语言包管理工具Godep的用法

    Go语言包管理工具Godep的用法

    这篇文章介绍了Go语言包管理工具Godep的用法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07

最新评论