解决 GORM + MySQL 5.7 报错:Error 1067: Invalid default value for ‘updated_at‘

当然可以!以下是一篇结构清晰、技术准确、适合发布在博客(如掘金、CSDN、个人博客等)的总结文章,标题和内容都已优化,便于读者理解和搜索:

🐞 解决 GORM + MySQL 5.7 报错:Error 1067: Invalid default value for 'updated_at'

关键词:GORM、MySQL 5.7、sql_mode、NO_ZERO_DATE、Error 1067、AutoMigrate、时间字段默认值

📌 问题现象

在使用 GORM(Go ORM) 自动建表(AutoMigrate)时,程序启动失败,报错如下:

Error 1067 (42000): Invalid default value for 'updated_at'

数据库环境:

MySQL 5.7.26(通过 phpStudy Pro 管理)

字符集:utf8

默认引擎原为 MyISAM,后改为 InnoDB

🔍 根本原因

MySQL 5.7 默认启用了严格的 sql_mode,其中包括:

text

NO_ZERO_DATE, NO_ZERO_IN_DATE, STRICT_TRANS_TABLES

这些模式会禁止使用 '0000-00-00' 或 '0000-00-00 00:00:00' 作为日期默认值。

而 GORM 在未显式指定时间字段类型时,可能生成类似这样的建表语句:

sql

updated_at datetime NOT NULL

由于字段为 NOT NULL 但没有合法默认值,MySQL 在严格模式下拒绝创建表,抛出 Error 1067。

💡 注意:即使你没手动写 DEFAULT '0000-00-00',GORM 的默认行为在某些配置下仍会触发零值逻辑。

✅ 解决方案(两种思路)

方案一:调整 MySQL 配置(适合本地开发)

  1. 修改 my.ini(phpStudy 路径示例):
    ini

    mysqld

    sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
    ✅ 移除了 NO_ZERO_DATE 和 NO_ZERO_IN_DATE,保留其他安全限制。
  2. 重启 MySQL 服务
  3. 验证生效:
    sql
    SELECT @@sql_mode;
    -- 确保输出中不含 NO_ZERO_DATE

✅ 优点:快速解决,无需改代码

⚠️ 缺点:降低数据校验强度,不建议用于生产环境

方案二:规范 GORM 模型定义(推荐长期使用)

在 Go 模型中显式指定时间字段类型和默认值:

go

import "time"

type BaseModel struct {

CreatedAt time.Time gorm:"type:timestamp;not null;default:CURRENT_TIMESTAMP"

UpdatedAt time.Time gorm:"type:timestamp;not null;default:CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"

}

type Block struct {

ID uint gorm:"primarykey"

Hash string gorm:"uniqueIndex;size:333"

BaseModel

}

同时,在 AutoMigrate 时指定表引擎和行格式:

go

db.Set("gorm:table_options", "ENGINE=InnoDB ROW_FORMAT=DYNAMIC").

AutoMigrate(&Block{})

✅ 优点:

兼容严格模式

支持大索引(避免 Error 1071: Specified key was too long)

代码可移植性强

🧪 额外建议

  1. 确保使用 InnoDB 引擎

    在 my.ini 中设置:

    ini

    default-storage-engine=InnoDB

  2. 索引字段加长度限制(防 Error 1071):

    go

    Hash string gorm:"uniqueIndex;size:333" // utf8 下 333*3=999 < 1000

  3. 未来考虑迁移到 utf8mb4

    支持 emoji 和完整 Unicode,索引长度建议 size:191

✅ 总结

问题 原因 推荐解法


Error 1067: Invalid default value for 'updated_at' MySQL 严格模式禁止零日期,GORM 默认字段定义不合规 显式定义 type:timestamp + 合法默认值

Error 1071: Specified key was too long MyISAM 引擎索引限制 1000 字节 使用 InnoDB + ROW_FORMAT=DYNAMIC + 限制字段长度

最佳实践:保持 MySQL 严格模式开启,从代码层面保证数据合法性,而不是关闭安全限制。

📚 参考资料
MySQL 5.7 sql_mode 官方文档
GORM 模型字段定义
InnoDB 行格式与大索引支持

希望这篇总结对你有帮助!欢迎转发、收藏,也欢迎在评论区交流你的踩坑经历 😊

你可以直接复制这段内容发布到博客平台,如需 Markdown 或 HTML 版本,也可以告诉我!

相关推荐
五阿哥永琪1 小时前
MySQL 慢查询定位与 SQL 性能优化实战指南
sql·mysql·性能优化
xiaok4 小时前
GROUP BY进阶用法
mysql
李慕婉学姐5 小时前
【开题答辩过程】以《基于Android的健康助手APP的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
android·java·mysql
qq_12498707535 小时前
基于springboot健康养老APP的设计与实现(源码+论文+部署+安装)
java·spring boot·后端·mysql·微信小程序·毕业设计
亚林瓜子5 小时前
mysql命令行手动导入csv数据到指定表
数据库·mysql·gui·csv·cli·db·import
一分半心动6 小时前
lnmp架构 mysql数据库Cannot assign requested address报错解决
linux·mysql·php
ChristXlx6 小时前
Linux安装mysql(虚拟机适用)
linux·mysql
瀚高PG实验室7 小时前
timestampdiff (MYSQL)函数在Highgo DB中的写法
数据库·mysql·瀚高数据库
还是鼠鼠7 小时前
SQL语句执行很慢,如何分析呢?
java·数据库·mysql·面试
云和数据.ChenGuang7 小时前
批量给100台服务器装系统,还要完成后续的配置和软件部署
运维·服务器·开发语言·mysql