【问题标题】:NodeJS sequelize auto generate models and run migrations SQL syntax errorNodeJS sequelize 自动生成模型并运行迁移 SQL 语法错误
【发布时间】:2019-09-27 09:26:25
【问题描述】:

我正在使用 MySQL 构建一个新的 NodeJS 应用程序。我需要使用现有的数据库模式。我有一个加载到数据库中的 mysql 转储文件(在 docker 容器中)。我正在尝试自动生成模型和迁移,然后成功运行迁移。我能够生成模型和迁移,但是运行生成的迁移时出现 SQL 语法错误。

以下是相关版本:

Node10-高山

"mysql": "^2.17.1",
"mysql2": "^1.6.5",
"sequelize": "^5.8.5",
"sequelize-auto": "^0.4.29",
"sequelize-auto-migrations": "^1.0.3"

我使用sequelize-auto 模块自动生成模型。这行得通。

sequelize-auto -o "./models" -d sequelize_auto_test -h localhost -u username -p 5432 -x password -e mysql

然后我尝试使用 sequelize-auto-migrations 模块生成迁移,然后自动运行它们。

生成初始迁移文件有效。

node ./node_modules/sequelize-auto-migrations/bin/makemigration --name <initial_migration_name>

但是,在运行实际迁移时,会出现语法错误。

node ./node_modules/sequelize-auto-migrations/bin/runmigration

这适用于许多表,但随后会遇到语法错误。

     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;' }

这里是相关的模型osw.js(由sequelize-auto模块生成):

/* 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'
  });
};

这里是mysql转储文件的相关部分:

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;

更新:我认为问题可能与自动生成的迁移有关。迁移文件似乎缺少列和字段类型定义,因此这可能是 SQL CREATE table 命令缺少列名的原因。以下是针对osw 表生成的迁移文件的相关部分:

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

            },
            {}
        ]
    }
];

【问题讨论】:

    标签: mysql node.js model migration sequelize.js


    【解决方案1】:
    • 是的,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. 这产生了 migrations/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
    };
    

    这解决了眼前的问题,但没有解释它。我清理了目录,初始化了包,安装了所有依赖项,并尝试再次生成迁移。这产生了一个空的 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 时为您的模型生成。不知道根本原因是什么。

    【讨论】:

      猜你喜欢
      • 2021-03-17
      • 2015-03-06
      • 2020-02-01
      • 2021-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-29
      • 2015-02-15
      相关资源
      最近更新 更多