You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 09:15:00