必须换纯go驱动,因gorm.io/driver/sqlite依赖cgo,在cgo_enabled=0默认模式下编译失败;modernc.org/sqlite可替代,支持gorm v1.25+,dsn需含_busy_timeout和_journal_mode=wal参数确保并发稳定。

直接用 gorm.io/driver/sqlite 会报 missing CGO 错误,必须换驱动 —— 这是新手最常卡住的地方。
为什么 gorm.io/driver/sqlite 在多数环境跑不起来
这个官方 SQLite 驱动依赖 CGO,而 Go 的默认构建模式(CGO_ENABLED=0)下无法编译;Windows、Alpine Linux、某些 CI 环境默认禁用 CGO,一跑就报错:build constraints exclude all Go files 或 missing cgo。
解决办法不是开 CGO,而是换纯 Go 实现的驱动:
- 用
modernc.org/sqlite替代gorm.io/driver/sqlite - 安装命令:
go get modernc.org/sqlite - GORM v1.25+ 已内置适配该驱动,无需额外封装
连接 SQLite 的正确写法(含路径与权限)
DSN 就是文件路径,但要注意三类常见问题:
- 路径必须是绝对路径或相对当前工作目录(不是源码目录),比如
./data/app.db,运行前确保data/目录存在且可写 - SQLite 不支持用户名/密码,DSN 格式就是:
./mydb.db?_busy_timeout=5000&_journal_mode=WAL - 推荐加两个参数:
_busy_timeout避免并发写冲突,_journal_mode=WAL提升读写并发能力
示例代码片段:
import (
"gorm.io/gorm"
"modernc.org/sqlite"
)
db, err := gorm.Open(sqlite.Open("./app.db?_busy_timeout=5000&_journal_mode=WAL"), &gorm.Config{})
if err != nil {
panic(err)
}
AutoMigrate 后表没建成功?检查这三点
SQLite 的 AutoMigrate 行为和 MySQL 不同,容易静默失败:
- 结构体字段没加
gorm:"primarykey",GORM 默认不会设主键 → SQLite 报错但不抛异常 - 字段名含大写字母或特殊符号(如
CreatedAt),SQLite 默认转成小写,但 GORM 可能映射失败 - 没调用
db.Exec("PRAGMA journal_mode = WAL")就直接迁移,WAL 模式未生效导致后续写入失败
建议迁移前显式确认连接可用:db.Exec("SELECT 1").Error,再执行 AutoMigrate。
并发写入时报 database is locked 怎么办
SQLite 默认的锁机制对高并发不友好,单纯加大 _busy_timeout 只是掩盖问题:
- 避免在 HTTP handler 中直接复用同一个
*gorm.DB做长事务(比如上传+解析+写库) - 用
db.Session(&gorm.Session{PrepareStmt: true})开启预处理语句,减少锁持有时间 - 真正需要并发写的场景,别硬扛 —— SQLite 本质是嵌入式数据库,单机高频写入请换 PostgreSQL 或加队列缓冲
最易忽略的一点:SQLite 的 WAL 模式只在连接首次打开时生效,重启应用后若 DSN 里没带 _journal_mode=WAL,它就退回到默认的 DELETE 模式,锁问题立刻重现。











