Sequelize设置TIMESTAMP ON UPDATE属性插入报SQL语法错误
问题产生原因
报错的核心原因是字段配置逻辑错误:
ON UPDATE CURRENT_TIMESTAMP是MySQL建表阶段为TIMESTAMP字段配置的更新触发规则,不属于字段默认值的范畴。- 你将这段完整语句写到了
updatedAt字段的defaultValue配置中,Sequelize在生成INSERT语句时,会把defaultValue里的literal内容直接作为插入值拼接到SQL中,最终生成的INSERT语句会在字段值位置出现CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,MySQL解析到值位置的ON UPDATE关键字就会抛出语法错误,和报错提示的位置完全吻合。
另外你手动关闭了Sequelize内置的时间戳自动维护能力(timestamps: false),又自己重复实现时间字段逻辑,本身就容易出现配置冲突。
解决方法
方案1:使用Sequelize内置时间戳配置(推荐)
这是最稳妥、兼容性最好的写法,不需要手动定义两个时间字段,Sequelize会自动处理字段映射、默认值、更新自动刷新时间的全部逻辑:
export const User = sequelize.define( 'user', { id: { type: DataTypes.INTEGER, allowNull: false, primaryKey: true, autoIncrement: true, }, name: { type: DataTypes.STRING(15), allowNull: false }, nickname: { type: DataTypes.STRING(15), allowNull: false }, email: { type: DataTypes.STRING(15), allowNull: false, unique: true }, password: { type: DataTypes.STRING(15), allowNull: false }, role: { type: DataTypes.STRING(30), allowNull: false, defaultValue: 'USER', }, // 移除手动定义的createdAt、updatedAt字段 }, { timestamps: true, // 开启自动时间戳维护 underscored: true, // 自动将驼峰命名的模型字段映射为数据库下划线命名字段,即createdAt -> created_at、updatedAt -> updated_at } );
该配置下Sequelize建表时会自动为updated_at字段加上ON UPDATE CURRENT_TIMESTAMP属性,插入、更新操作都不会生成语法错误的SQL。
方案2:保留手动定义字段的写法
如果需要自定义时间字段的更多属性,坚持手动定义,不要把ON UPDATE规则写到defaultValue中,Sequelize 6提供了专门的onUpdate配置项来声明更新触发规则:
export const User = sequelize.define( 'user', { id: { type: DataTypes.INTEGER, allowNull: false, primaryKey: true, autoIncrement: true, }, name: { type: DataTypes.STRING(15), allowNull: false }, nickname: { type: DataTypes.STRING(15), allowNull: false }, email: { type: DataTypes.STRING(15), allowNull: false, unique: true }, password: { type: DataTypes.STRING(15), allowNull: false }, role: { type: DataTypes.STRING(30), allowNull: false, defaultValue: 'USER', }, createdAt: { type: DataTypes.TIMESTAMP, // 不要用字符串'TIMESTAMP',直接引用DataTypes的类型避免解析错误 allowNull: false, defaultValue: sequelize.literal('CURRENT_TIMESTAMP'), field: 'created_at', }, updatedAt: { type: DataTypes.TIMESTAMP, allowNull: false, defaultValue: sequelize.literal('CURRENT_TIMESTAMP'), onUpdate: sequelize.literal('CURRENT_TIMESTAMP'), // 单独配置更新触发规则,建表时会自动拼接ON UPDATE子句 field: 'updated_at', }, }, { timestamps: false } );
注意:如果之前已经用错误配置同步生成过表结构,需要先删除旧的
users表,或者手动修改updated_at字段的默认值配置,再重新同步表结构,否则旧表的错误字段定义会持续导致问题。
内容的提问来源于stack exchange,提问作者devamos
相关产品推荐
相关产品推荐

