必须显式导入 _ "gorm.io/driver/sqlite",否则 gorm.open 会 panic 报 unsupported driver: sqlite;需用下划线触发驱动 init() 注册,路径须为 gorm.io/driver/sqlite,且 sqlite 外键、wal 等 pragma 需 open 后手动 exec 启用。

必须显式导入 _ "gorm.io/driver/sqlite",否则 gorm.Open 会 panic 报 unsupported driver: sqlite —— 这是 90% 新手卡住的第一步。
为什么 gorm.Open(sqlite.Open("db.db")) 直接 panic?
根本原因是 GORM 的 SQLite 驱动没注册。GORM v2(gorm.io/gorm)不内置驱动逻辑,靠 init() 函数注册,而该函数只在包被“使用”时触发。仅写 import "gorm.io/driver/sqlite" 不够,必须加下划线:
-
import _ "gorm.io/driver/sqlite"✅(触发init,完成注册) -
import "gorm.io/driver/sqlite"❌(包未被引用,init不执行) - 路径必须是
gorm.io/driver/sqlite,不是旧版github.com/mattn/go-sqlite3或github.com/jinzhu/gorm/dialects/sqlite - 确认
go.mod中有类似gorm.io/driver/sqlite v1.5.0的条目,版本太低可能缺失 WAL 支持等特性
sqlite.Open("xxx") 的路径写法和行为差异
参数传给 sqlite.Open 的字符串决定数据库是磁盘、内存还是带配置的持久化实例,行为差别极大:
-
sqlite.Open("app.db"):磁盘文件,不存在则创建,需确保进程对路径有读写权限 -
sqlite.Open(":memory:"):纯内存 DB,每次Open都是全新空库,进程退出即销毁 -
sqlite.Open("app.db?_journal_mode=WAL&_busy_timeout=5000"):启用 WAL 模式提升并发写性能,&是 Go 字符串里的普通&,不用 HTML 转义 - SQLite 默认不启用外键约束,哪怕模型写了
foreignKey标签,也得手动执行:db.Exec("PRAGMA foreign_keys = ON")
第一次 AutoMigrate 就失败?检查这些硬伤
SQLite 的 ALTER TABLE 能力弱,AutoMigrate 在已有表上增删字段、改类型、加唯一约束时容易静默失败或跳过:
- 开发阶段建议用全新 DB 文件(如
test_dev.db),避免反复迁移污染状态 - 含多对多关系(如
User↔Role)时,AutoMigrate(&User{})不会自动建关联表,必须提前调用:db.SetupJoinTable(&User{}, "Roles", &UserRole{}) - 想修改已存在字段(比如把
name string改成name *string),别依赖AutoMigrate,改用:db.Migrator().AddColumn(&User{}, "name_new")+ 原生 SQL 搬数据 +DropColumn - 如果表已存在且结构复杂,直接
db.Migrator().CreateTable(&User{})会报错,它只建新表,不覆盖
最容易被忽略的是:SQLite 的外键、WAL、busy timeout 等全是运行时 pragma,不是连接字符串一设就生效——必须在 gorm.Open 后立刻 Exec 开关,否则模型里写的约束形同虚设。











