GORM连接MySQL必须使用Go原生驱动go-sql-driver/mysql,不可用Python的pymysql或mysqlclient;DSN格式须为user:pass@tcp(host:port)/db?params,且需设parseTime=True和loc=Local以正确处理时间类型。

直接用 GORM + mysql 驱动就能连,别碰 pymysql 或其他 Python 风格驱动——Go 生态不认那个。
为什么不能用 pymysql 或 mysqlclient
Flask 里用 pymysql 是因为 Python 没原生 MySQL 驱动;Go 有官方维护的 go-sql-driver/mysql,GORM 默认就靠它。你硬塞 Python 的驱动进去,编译都过不了——import "pymysql" 在 Go 里根本不存在。
-
go get github.com/go-sql-driver/mysql是必须的,不是可选 - GORM v1.25+ 默认使用该驱动,不用额外注册
- 如果误装了
github.com/ziutek/mymysql这类老库,会报undefined: mysql.Register类似错误
gorm.Open() 的 DSN 格式和常见拼写错误
MySQL 的 DSN 必须严格按 user:password@tcp(host:port)/dbname?params 格式,少一个 tcp() 或漏掉 ? 都会 panic。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
- 正确示例:
"root:123456@tcp(127.0.0.1:3306)/myapp?charset=utf8mb4&parseTime=True&loc=Local" - 错把
localhost当成 IP:MySQL 8.0 默认禁用localhost的 socket 连接,换成127.0.0.1更稳 -
&是 URL 参数分隔符,不是&(XML 实体),写错会导致参数被截断 - 中文字段必须加
charset=utf8mb4,否则存成问号或报错Incorrect string value
在 Fiber 中初始化并注入 DB 实例
Fiber 没有 Flask 那种全局 app.config,DB 要手动传进路由或挂到 fiber.Ctx.Locals,但更推荐依赖注入方式。
- 在
main.go初始化后,用app.Use(func(c *fiber.Ctx) error { c.Locals("db", db); return c.Next() })挂载 - 或者定义结构体:
type Handler struct { DB *gorm.DB },然后handler := &Handler{DB: db},再绑定路由 - 别在每个 handler 里重复调
gorm.Open()——连接池会爆,且sql: database is closed错误频发 - 记得调
db.Exec("SELECT 1")做一次连通性验证,避免服务启动成功但数据库实际不可达
事务控制与自动提交陷阱
GORM 默认开启自动提交,但 Fiber 的请求生命周期短,容易忽略手动事务管理。
- 需要事务时,必须显式调
tx := db.Begin(),并在成功后tx.Commit(),失败时tx.Rollback() - 别依赖
defer tx.RollbackUnlessCommitted()——它只在 panic 时生效,逻辑错误不会触发 - 在 Fiber 中,
c.Context().Done()可能提前关闭,建议用context.WithTimeout包裹 DB 操作 - 注意
db.Save()和db.Create()行为差异:前者更新非零字段,后者强制 INSERT,混用会导致数据覆盖或主键冲突
最常被跳过的一步是验证 MySQL 用户权限和网络可达性——mysql -u root -p -h 127.0.0.1 -P 3306 能连上,不代表 Go 进程能连上,容器环境尤其要注意 host 网络模式和端口映射。

















