NodeJS sequelize 自动生成模型并运行迁移 SQL 语法错误
Posted
技术标签:
【中文标题】NodeJS sequelize 自动生成模型并运行迁移 SQL 语法错误【英文标题】:NodeJS sequelize auto generate models and run migrations SQL syntax error 【发布时间】: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",
,
]
];
【问题讨论】:
【参考方案1】: 是的,SQL 错误是因为括号之间应该有一个列列表。 是的,迁移文件应包含列而不是空括号,如本答案下方的正确文件所示。 错误迁移的原因似乎与您的 package.json 中指定的最新 Sequelize 版本有关。这个答案的其余部分解释了这个过程。您的 sequelize-auto 输出看起来很正常,因此我尝试仅重现迁移步骤:
-
在新目录中运行
sequelize init
(未明确安装,NPM 显示 4.44)并将 osw.js 粘贴到 ./models 中。
安装 mysql2 和 sequelize-auto-migrations 的匹配版本,调用 node ./node_modules/sequelize-auto-migrations/bin/makemigration --name osw
的最低要求
这产生了 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 时为您的模型生成。不知道根本原因是什么。
【讨论】:
以上是关于NodeJS sequelize 自动生成模型并运行迁移 SQL 语法错误的主要内容,如果未能解决你的问题,请参考以下文章
Nodejs / PostgreSQL sequelize - 如何更新/更改数据库中的模型?