Knex.js配置MySQL updated_at自动更新触发器执行迁移报错如何解决
报错原因
你写的自定义函数和触发器语法是PostgreSQL数据库的专属语法,完全不兼容MySQL,具体不兼容点如下:
- MySQL没有
RETURNS trigger的函数定义语法,触发器逻辑不需要封装成独立函数,直接写在触发器声明中即可 $$是PostgreSQL的函数体定界符,MySQL不识别该语法- MySQL触发器不支持
EXECUTE PROCEDURE调用自定义函数的用法,属于PostgreSQL专属特性
修复方案
有两种更适配MySQL的实现方案,推荐优先使用第一种,逻辑更简洁无需额外维护触发器:
方案1:直接使用MySQL原生字段属性(推荐)
MySQL的TIMESTAMP和DATETIME字段原生支持ON UPDATE CURRENT_TIMESTAMP属性,修改记录时会自动更新updated_at字段,完全不需要自定义函数和触发器。
只需要修改用户表迁移文件的updated_at字段定义即可:
exports.up = async (knex) => { await knex.schema.createTable('users', (table) => { table.increments('id') table.string('email').notNullable() table.string('password').notNullable() table.string('reset_token') table.timestamp('reset_expires') table.timestamp('created_at').defaultTo(knex.fn.now()) // 新增.onUpdate()方法,knex会自动生成MySQL的ON UPDATE CURRENT_TIMESTAMP属性 table.timestamp('updated_at').defaultTo(knex.fn.now()).onUpdate(knex.fn.now()) }) // 不需要再执行触发器创建逻辑 }
同时可以直接删除之前的自定义函数迁移文件,以及knexfile.js里的onUpdateTrigger相关代码即可。
方案2:自定义触发器实现
如果业务需求必须用触发器实现,修改knexfile.js里的onUpdateTrigger方法为MySQL兼容语法即可,无需额外创建自定义函数:
onUpdateTrigger: (table) => ` CREATE TRIGGER ${table}_updated_at BEFORE UPDATE ON ${table} FOR EACH ROW SET NEW.updated_at = CURRENT_TIMESTAMP; `
同时删除之前的自定义函数迁移文件即可,原用户表迁移代码不需要额外修改。
内容的提问来源于stack exchange,提问作者João Lucas
相关产品推荐
相关产品推荐

