使用sequelize-cli执行db:migrate时报SQL语法错误该如何解决?
问题根源
你报错的直接原因是:Sequelize 中的 NUMBER 是 PostgreSQL 专属数据类型,MySQL 没有对应语法,执行迁移时会直接往SQL语句里插入NUMBER关键字,导致MySQL解析失败。
修复步骤
1. 修正迁移文件字段类型
手机号不建议使用数值类型存储(会丢失开头的0、+号等特殊字符),建议改为STRING类型,如果你确实需要数值类型可以改为BIGINT。
修正后的迁移文件代码:
'use strict'; module.exports = { up: async (queryInterface, Sequelize) => { await queryInterface.createTable('Users', { id: { allowNull: false, autoIncrement: true, primaryKey: true, type: Sequelize.INTEGER }, name: { type: Sequelize.STRING, allowNull: false }, phone_number: { // 替换原来的NUMBER类型 type: Sequelize.STRING }, otp: { type: Sequelize.INTEGER }, otp_expiration_date: { type: Sequelize.DATE }, createdAt: { allowNull: false, type: Sequelize.DATE }, updatedAt: { allowNull: false, type: Sequelize.DATE } }) }, down: async (queryInterface, Sequelize) => { await queryInterface.dropTable('Users'); } };
2. 同步修正User模型的字段类型+修复隐藏BUG
你的模型里有三处隐藏问题:
phone_number同样使用了NUMBER类型,需要和迁移文件同步修改- 虚拟字段
is_otp_expired的getDataValue参数没有加引号,会报变量未定义错误 is_otp_expired的判断逻辑写反:otp_expiration_date在当前时间之后说明OTP未过期,应该返回false
修正后的模型代码:
const moment = require('moment'); const { Model } = require('sequelize'); // 原代码漏了导入Model,此处补上 'use strict'; module.exports = (sequelize, DataTypes) => { class User extends Model { /** * 关联关系定义辅助方法,不属于Sequelize生命周期 * models/index.js文件会自动调用该方法 */ static associate(models) { // 在此处定义关联关系 } }; User.init({ name: { type: DataTypes.STRING, allowNull: false }, phone_number: { // 替换原来的NUMBER类型 type: DataTypes.STRING }, otp: { type: DataTypes.INTEGER }, otp_expiration_date: { type: DataTypes.DATE, set(value) { // 将普通Date转换为moment日期对象 value = moment(value).add(5, 'minutes'); this.setDataValue('otp_expiration_date', value); } }, is_otp_expired: { type: DataTypes.VIRTUAL, get() { // 修复参数加引号、逻辑修正 return !moment(this.getDataValue('otp_expiration_date')).isAfter(moment()); } } }, { sequelize, modelName: 'User', }); return User; };
3. 重新执行迁移
删除数据库中之前可能生成的不完整Users表,再执行迁移命令即可:npx sequelize-cli db:migrate
内容的提问来源于stack exchange,提问作者Muhammad Uzair
相关产品推荐
相关产品推荐

