GoAdmin 兼容低版本的 MySQL,Unknown character set: 'utf8mb4'

文章目录

    有一个历史悠久的服务,使用的是 MySQL 5.0 版本。我想用 GoAdmin 重写管理后台,但是 MySQL 又不敢停机升级。发布之后,运行报错:

    panic: Error 1115: Unknown character set: 'utf8mb4'
    
    goroutine 1 [running]:
    github.com/GoAdminGroup/go-admin/modules/db.(*Mysql).InitDB.func1()
            /home/zhongwei/golang/pkg/mod/github.com/!go!admin!group/go-admin@v1.2.9/modules/db/mysql.go:66 +0x403
    

    推测 MySQL 低版本还不支持 utf8mb4。查看 MySQL 不同版本对 utf8mb4 的支持

    定位问题

    搜索了一下 GoAdmin 的源代码:

    grep utf8mb4 -r .
    ./modules/db/mysql.go
    

    发现 GoAdmin 是写死了 utf8mb4 编码,无法自定义编码设置。但是可以通过设置 cfg.Dsn 连接字符串的方式,来设置 charset 编码。

    // InitDB implements the method Connection.InitDB.
    func (db *Mysql) InitDB(cfgs map[string]config.Database) Connection {
    	db.Once.Do(func() {
    		for conn, cfg := range cfgs {
    
    			if cfg.Dsn == "" {
    				cfg.Dsn = cfg.User + ":" + cfg.Pwd + "@tcp(" + cfg.Host + ":" + cfg.Port + ")/" + cfg.Name + "?charset=utf8mb4"
    			}
    
    			sqlDB, err := sql.Open("mysql", cfg.Dsn)
    

    解决方法

    使用 Dsn 设置 charset 编码:

    // global config
    cfg := config.Config{
    	Databases: config.DatabaseList{
    		"default": {
    			MaxIdleCon: 50,
    			MaxOpenCon: 150,
    			Driver:     "mysql",
    			Dsn:        "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8",
    		},
    	},
    

    修改 SQL

    同时需要将 GoAdmin 自带的建表 SQL 中的 utf8mb4 都替换为 utf8.

    这还没有完,低版本的 MySQL 在建表时,还会报一个错:

    ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause

    需要将

    `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
    

    修改为

    `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
    `updated_at` timestamp NULL,
    

    updated_at 的自动更新,需要想想办法了。

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式