问题现象
近日遇到gorm连mysql代理报错(直连mysql不报错),错误如下:
执行db.AutoMigrate函数报:Table already exists
执行db.First函数报:Unknown prepared statement handler given to mysqld_stmt_execute
原因分析
由于使用的mysql代理不支持prepare操作导致
解决方法
这个问题目前已经找到解决方法,请看下文。
使用gorm有2种方式,第1种是import gorm.io/gorm,另外1种是import github.com/jinzhu/gorm。第1种:
import (
"gorm.io/gorm"
"gorm.io/driver/mysql"
"fmt"
)
...
db, err = gorm.Open(mysql.Open("user:password@tcp(ip:port)/database?charset=utf8&parseTime=True&loc=Local"), &gorm.Config{PrepareStmt: true})
...
第2种:
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"fmt"
)
...
db, err = gorm.Open("mysql", "user:password@tcp(ip:port)/database?charset=utf8&parseTime=True&loc=Local")
...
对于第1种和第2种,均需要在数据库的url里加上:interpolateParams=True,也即:
"user:password@tcp(ip:port)/database?charset=utf8&parseTime=True&loc=Local&interpolateParams=True"
加上interpolateParams=True后客户端会关闭prepare处理,此时问题就已经解决了吗?答案是没有完全解决。
实际跑下来第2种用法已经ok了,但是第1种还有问题,而且是同样的报错,此处必有蹊跷,烧脑思考中。。。
原来在第1种gorm.Open用法里有:PrepareStmt: true,去掉再跑就好了。
---------------------------------------------------------------------------------------------------------------------------------
题外话
以下是题外话,顺带提下搭建go环境的问题处理方法,在使用go get报i/o timeout的情况下,可以从github上根据tag下载好相应版本源码的zip包,解压到本地,再在源码工程go.mod里使用replace语句,例如,
replace gorm.io/gorm => /home/xxx/gorm.io/gorm
replace gorm.io/driver/mysql => /home/xxx/gorm.io/driver/mysql
第1种用法的gorm仓库地址: go-gorm · GitHubhttps://github.com/go-gorm
第2种用法的gorm仓库地址:jinzhu (Jinzhu) · GitHubhttps://github.com/jinzhu