NodeJS sequelize auto generate models and run migrations SQL syntax error

pen*_*ngz 6 mysql migration model node.js sequelize.js

I am building a new NodeJS application with MySQL. I need to use the existing database schema. I have a mysql dump file that is loaded into the database (in a docker container). I am trying to generate models and migrations automatically and then run the migrations successfully. I am able to generate the models and migrations, however there is a SQL syntax error when running the generated migrations.

Here are the relevant versions:

Node10-alpine

"mysql": "^2.17.1",
"mysql2": "^1.6.5",
"sequelize": "^5.8.5",
"sequelize-auto": "^0.4.29",
"sequelize-auto-migrations": "^1.0.3"
Run Code Online (Sandbox Code Playgroud)

I used the sequelize-auto module to generate the Models automatically. That works.

sequelize-auto -o "./models" -d sequelize_auto_test -h localhost -u username -p 5432 -x password -e mysql
Run Code Online (Sandbox Code Playgroud)

I then attempted to use the sequelize-auto-migrations module to generate the Migrations and then run them automatically.

Generating the initial migration file works.

node ./node_modules/sequelize-auto-migrations/bin/makemigration --name <initial_migration_name>
Run Code Online (Sandbox Code Playgroud)

However, when running the actual migration, there is a syntax error.

node ./node_modules/sequelize-auto-migrations/bin/runmigration
Run Code Online (Sandbox Code Playgroud)

That works for many of the tables but then it runs into a syntax error.

     code: 'ER_PARSE_ERROR',
     errno: 1064,
     sqlState: '42000',
     sqlMessage:
      'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \') ENGINE=InnoDB\' at line 1',
     sql: 'CREATE TABLE IF NOT EXISTS `osw` () ENGINE=InnoDB;' },
  sql: 'CREATE TABLE IF NOT EXISTS `osw` () ENGINE=InnoDB;' }
Run Code Online (Sandbox Code Playgroud)

Here is the relevant model osw.js (generated by the sequelize-auto module):

/* jshint indent: 2 */

module.exports = function(sequelize, DataTypes) {
  return sequelize.define('osw', {
    OSWID: {
      type: DataTypes.INTEGER(10).UNSIGNED,
      allowNull: false,
      primaryKey: true
    },
    IdentificationID: {
      type: DataTypes.INTEGER(10).UNSIGNED,
      allowNull: true,
      references: {
        model: 'itemidentification',
        key: 'IdentificationID'
      }
    },
    ProposedHours: {
      type: DataTypes.DECIMAL,
      allowNull: true
    },
    WorkStartDate: {
      type: DataTypes.DATEONLY,
      allowNull: true
    },
    WorkEndDate: {
      type: DataTypes.DATEONLY,
      allowNull: true
    },
    FormatID: {
      type: DataTypes.INTEGER(10).UNSIGNED,
      allowNull: true,
      references: {
        model: 'formats',
        key: 'FormatID'
      }
    },
    WorkLocationID: {
      type: DataTypes.INTEGER(10).UNSIGNED,
      allowNull: true
    }
  }, {
    tableName: 'osw'
  });
};
Run Code Online (Sandbox Code Playgroud)

Here is the relevant part of the mysql dump file:

CREATE TABLE `OSW` (
  `OSWID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `IdentificationID` int(10) unsigned DEFAULT NULL,
  `ProposedHours` decimal(10,2) DEFAULT NULL,
  `WorkStartDate` date DEFAULT NULL,
  `WorkEndDate` date DEFAULT NULL,
  `FormatID` int(10) unsigned DEFAULT NULL,
  `WorkLocationID` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`OSWID`),
  KEY `OSW_FKIndex1` (`IdentificationID`),
  KEY `OSW_Format` (`FormatID`),
  CONSTRAINT `OSW_Format` FOREIGN KEY (`FormatID`) REFERENCES `formats` (`formatid`) ON DELETE SET NULL,
  CONSTRAINT `OSW_Ident` FOREIGN KEY (`IdentificationID`) REFERENCES `itemidentification` (`identificationid`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1147 DEFAULT CHARSET=utf8 PACK_KEYS=0;
Run Code Online (Sandbox Code Playgroud)

UPDATE: I think the issue might be related to the migration that was generated automatically. The migration file seems to be missing the column and field type definitions, so that might be why the SQL CREATE table command is missing the column names. Here is the relevant part of the migration file that was generated regarding the osw table:

var migrationCommands = [{
    {
        fn: "createTable",
        params: [
            "osw",
            {

            },
            {}
        ]
    }
];
Run Code Online (Sandbox Code Playgroud)

MBe*_*Ber 6

  • 是的,SQL 错误是因为括号之间应该有一个列列表。
  • 是的,迁移文件应包含列而不是空括号,如本答案下方的正确文件所示。
  • 错误迁移的原因似乎与 package.json 中指定的最新 Sequelize 版本有关。这个答案的其余部分解释了这个过程。

您的 sequelize-auto 输出看起来正常,因此我尝试通过以下方式仅重现迁移步骤:

  1. sequelize init在新目录中运行(未明确安装,NPM 显示为 4.44)并将 osw.js 粘贴到 ./models 中。
  2. 安装匹配版本的 mysql2 和 sequelize-auto-migrations,这是调用的最低要求 node ./node_modules/sequelize-auto-migrations/bin/makemigration --name osw
  3. 这产生了迁移/1-osw.js:
'use strict';

var Sequelize = require('sequelize');

/**
 * Actions summary:
 *
 * createTable "osw", deps: [itemidentification, formats]
 *
 **/

var info = {
    "revision": 1,
    "name": "osw",
    "created": "2019-05-30T03:54:19.054Z",
    "comment": ""
};

var migrationCommands = [{
    fn: "createTable",
    params: [
        "osw",
        {
            "OSWID": {
                "type": Sequelize.INTEGER(10).UNSIGNED,
                "field": "OSWID",
                "primaryKey": true,
                "allowNull": false
            },
            "IdentificationID": {
                "type": Sequelize.INTEGER(10).UNSIGNED,
                "field": "IdentificationID",
                "references": {
                    "model": "itemidentification",
                    "key": "IdentificationID"
                },
                "allowNull": true
            },
            "ProposedHours": {
                "type": Sequelize.DECIMAL,
                "field": "ProposedHours",
                "allowNull": true
            },
            "WorkStartDate": {
                "type": Sequelize.DATEONLY,
                "field": "WorkStartDate",
                "allowNull": true
            },
            "WorkEndDate": {
                "type": Sequelize.DATEONLY,
                "field": "WorkEndDate",
                "allowNull": true
            },
            "FormatID": {
                "type": Sequelize.INTEGER(10).UNSIGNED,
                "field": "FormatID",
                "references": {
                    "model": "formats",
                    "key": "FormatID"
                },
                "allowNull": true
            },
            "WorkLocationID": {
                "type": Sequelize.INTEGER(10).UNSIGNED,
                "field": "WorkLocationID",
                "allowNull": true
            },
            "createdAt": {
                "type": Sequelize.DATE,
                "field": "createdAt",
                "allowNull": false
            },
            "updatedAt": {
                "type": Sequelize.DATE,
                "field": "updatedAt",
                "allowNull": false
            }
        },
        {}
    ]
}];

module.exports = {
    pos: 0,
    up: function(queryInterface, Sequelize)
    {
        var index = this.pos;
        return new Promise(function(resolve, reject) {
            function next() {
                if (index < migrationCommands.length)
                {
                    let command = migrationCommands[index];
                    console.log("[#"+index+"] execute: " + command.fn);
                    index++;
                    queryInterface[command.fn].apply(queryInterface, command.params).then(next, reject);
                }
                else
                    resolve();
            }
            next();
        });
    },
    info: info
};
Run Code Online (Sandbox Code Playgroud)

这解决了眼前的问题,但没有解释它。我清理了目录,初始化了包,安装了所有依赖项,并尝试再次生成迁移。这产生了一个空migrationCommands变量,就像你上面显示的那样。尝试卸载并重新安装各种软件包没有效果 - 我生成了十几次空。卸载 sequelize 导致错误,所以我从一个空目录和npm i -s mysql2 sequelize-auto-migrations; sequelize init. 从 osw.js 生成再次工作。

npm 显示 sequelize-auto-migrations 再次使用 sequelize 4.44。npm i sequelize安装了 5.8.7,并且生成立即开始失败。因此,sequelize-auto-migrations 只能在依赖于较早版本的 sequelize 时为您的模型生成。不知道根本原因是什么。