GORM v2 连接 SQLite 必须用 sqlite.Open("test.db") 构造 Dialector,不可直接传字符串路径;需开启 _foreign_keys=1 才支持外键约束,AutoMigrate 对字段增删改及主键索引变更基本无效。

gorm.Open 传参必须用 sqlite.Open 而非字符串路径
直接传 "test.db" 会 panic,GORM v2 不再接受裸路径。SQLite 驱动需显式调用 sqlite.Open 函数构造 DSN,并配合 gorm.Open 使用。
常见错误现象:failed to initialize database, got error: unsupported driver: test.db
- 正确写法:
gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) -
sqlite.Open返回的是gorm.Dialector,不是字符串,不能拼接或打印 - 若需附加 SQLite 参数(如
_foreign_keys=1),应写成sqlite.Open("test.db?_foreign_keys=1") - 注意:参数值需 URL 编码,例如数据库路径含空格时,用
url.PathEscape处理
启用外键约束需手动设置 _foreign_keys=1
SQLite 默认关闭外键支持,即使模型定义了 foreignKey 标签,ON DELETE CASCADE 等也不会生效。
使用场景:你写了 UserID uint + gorm.ForeignKey("UserID"),但删除用户后关联记录没被自动清理。
- 必须在 DSN 中开启:
sqlite.Open("app.db?_foreign_keys=1") - 仅靠
db.Exec("PRAGMA foreign_keys = 1")在连接后执行是不可靠的——每次新连接都需重设,且 GORM 连接池可能复用未初始化的连接 - 验证是否生效:
db.Exec("PRAGMA foreign_keys").Scan(&val),返回 1 表示已启用
迁移时 AutoMigrate 对 SQLite 的限制要心里有数
SQLite 的 ALTER TABLE 能力极弱,AutoMigrate 无法添加/删除列、修改字段类型或重命名字段(v1.24+ 仍不支持)。
容易踩的坑:开发中改了 struct 字段,跑一遍 AutoMigrate 就以为表结构同步了,结果字段根本没加进去。
- 新增字段:只有字段为 NULLABLE 且无默认值时,
AutoMigrate才能成功添加;否则会报no such column - 推荐做法:对 SQLite,尽量避免运行时变更结构;必须改时,手写
db.Migrator().AddColumn或用db.Exec执行原生ALTER TABLE ... ADD COLUMN - 主键和索引变更基本不支持,
AutoMigrate会静默跳过,不会报错也不会生效
测试环境用 :memory: 时要注意连接隔离性
sqlite.Open(":memory:") 创建的是独立内存数据库实例,每个 gorm.Open 调用都得到一个全新、空的库。
使用场景:单元测试中想快速建表跑断言,但发现 AutoMigrate 后查不到数据。
- 根本原因:测试中若多次调用
gorm.Open(比如每个 test case 都 new db),它们之间完全不共享数据 - 解决方案:全局复用一个
*gorm.DB实例,或在 test helper 中统一初始化并传入 - 别用
file::memory:?cache=shared试图共享——GORM 的连接池会干扰共享语义,行为不可控











