能跑通gorm+sqlite的最小可行配置是:正确导入驱动(import _ "gorm.io/driver/sqlite")、确保数据库路径可写且父目录存在(用os.mkdirall预创建)、显式启用外键(db.exec("pragma foreign_keys = on"))。漏任一环节,automigrate会静默失败或外键不生效。

能跑通 GORM + SQLite 的最小可行配置,就三件事:驱动导入正确、路径可写、外键手动开。漏掉任意一个,AutoMigrate 会静默失败,表建不出来,或者 foreign key 不生效。
import _ "gorm.io/driver/sqlite" 这行不能少
这是最常卡住的点——只写了 "gorm.io/gorm" 和 "gorm.io/driver/sqlite",没加下划线,gorm.Open 就会 panic 报 unsupported driver: sqlite。
原因在于 GORM 驱动靠 init() 函数注册,下划线导入才能触发它。正确写法是:
import (
"gorm.io/gorm"
_ "gorm.io/driver/sqlite" // 注意前面的 _
)
别用旧路径 github.com/mattn/go-sqlite3 或 github.com/jinzhu/gorm/dialects/sqlite,那些是 v1 版本,GORM v2 不兼容。
sqlite.Open("db.sqlite") 路径要可写,且目录得存在
sqlite.Open 不会自动创建父目录。如果路径是 "data/db.sqlite",而 data/ 目录不存在,gorm.Open 不报错,但后续 AutoMigrate 或任何写操作都会失败,错误可能是 no such table 或更模糊的 I/O 错误。
安全做法是提前确保目录就位:
- 用
os.MkdirAll(filepath.Dir("data/db.sqlite"), 0755)创建路径 - 或直接用
":memory:"做单元测试——每次都是干净实例,不落地 - 避免裸写相对路径如
"./db.sqlite",工作目录一变就找不到文件
FOREIGN KEY 默认不生效,必须显式启用
GORM 模型里写了 gorm:"foreignKey:UserID" 没用。SQLite 默认关闭外键约束,PRAGMA foreign_keys = OFF 是它的出厂设置。
连接打开后立刻执行:
db.Exec("PRAGMA foreign_keys = ON")
否则即使 AutoMigrate 生成了 FOREIGN KEY 语句,它也只是被解析、不执行约束。插入非法关联数据也不会报错,查起来像“数据丢了”。
也可以把 pragma 写进连接字符串:sqlite.Open("db.sqlite?_pragma=foreign_keys(1)"),效果一样,但不如代码里显式调用直观。
AutoMigrate 只增不改,已有表结构别指望它自动同步
它不会删字段、不会改类型、不会重命名列。比如你把 Name string 改成 Name *string,AutoMigrate 不会动原字段,也不会报错——只是新字段加进去,老数据还在那里。
开发阶段建议:
- 每次改模型前,删掉
db.sqlite文件,让 AutoMigrate 从头建 - 涉及字段变更时,用
db.Migrator().DropColumn或手写ALTER TABLE - 多对多关系记得先调
db.SetupJoinTable(&User{}, "Roles", &UserRole{}),否则关联表可能漏建
最易被忽略的是:SQLite 的 ALTER TABLE 功能极其有限,连改个字段类型都得靠重建表。别把它当 MySQL 用。











