Sequelize 无法创建 table 但是当我 运行 在 MySQL CLI 中创建相同时它可以工作

Sequelize can't create table but when I run the same in MySQL CLI it works

我正在使用 sequelize 并且 运行 出现了一个奇怪的错误:

Executing (default): CREATE TABLE IF NOT EXISTS `groups` (`id` INTEGER NOT NULL auto_increment , `groupname` VARCHAR(255), `groupkey` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
Executing (default): CREATE TABLE IF NOT EXISTS `users` (`id` INTEGER NOT NULL auto_increment , `username` VARCHAR(255) UNIQUE, `password` VARCHAR(255), `salt` VARCHAR(255), `token` VARCHAR(255), `group_id` INTEGER, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`), FOREIGN KEY (`group_id`) REFERENCES `groups` (`id`)) ENGINE=InnoDB;
Executing (default): CREATE TABLE IF NOT EXISTS `messages` (`id` INTEGER NOT NULL auto_increment , `message` VARCHAR(255), `group_id` INTEGER, `user_id` INTEGER, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`), FOREIGN KEY (`group_id`) REFERENCES `groups` (`id`), FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)) ENGINE=InnoDB;
Possibly unhandled SequelizeDatabaseError: ER_CANT_CREATE_TABLE: Can't create table 'crew.users' (errno: 150)
    at module.exports.Query.formatError (/home/ubuntu/public/server/node_modules/sequelize/lib/dialects/mysql/query.js:160:16)
    at Query._callback (/home/ubuntu/public/server/node_modules/sequelize/lib/dialects/mysql/query.js:38:23)
    at Query.Sequence.end (/home/ubuntu/public/server/node_modules/mysql/lib/protocol/sequences/Sequence.js:96:24)
    at Query.ErrorPacket (/home/ubuntu/public/server/node_modules/mysql/lib/protocol/sequences/Query.js:94:8)
    at Protocol._parsePacket (/home/ubuntu/public/server/node_modules/mysql/lib/protocol/Protocol.js:271:23)
    at Parser.write (/home/ubuntu/public/server/node_modules/mysql/lib/protocol/Parser.js:77:12)
    at Protocol.write (/home/ubuntu/public/server/node_modules/mysql/lib/protocol/Protocol.js:39:16)
    at Socket.<anonymous> (/home/ubuntu/public/server/node_modules/mysql/lib/Connection.js:82:28)
    at Socket.EventEmitter.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:746:14)
Possibly unhandled SequelizeDatabaseError: ER_CANT_CREATE_TABLE: Can't create table 'crew.messages' (errno: 150)
    at module.exports.Query.formatError (/home/ubuntu/public/server/node_modules/sequelize/lib/dialects/mysql/query.js:160:16)
    at Query._callback (/home/ubuntu/public/server/node_modules/sequelize/lib/dialects/mysql/query.js:38:23)
    at Query.Sequence.end (/home/ubuntu/public/server/node_modules/mysql/lib/protocol/sequences/Sequence.js:96:24)
    at Query.ErrorPacket (/home/ubuntu/public/server/node_modules/mysql/lib/protocol/sequences/Query.js:94:8)
    at Protocol._parsePacket (/home/ubuntu/public/server/node_modules/mysql/lib/protocol/Protocol.js:271:23)
    at Parser.write (/home/ubuntu/public/server/node_modules/mysql/lib/protocol/Parser.js:77:12)
    at Protocol.write (/home/ubuntu/public/server/node_modules/mysql/lib/protocol/Protocol.js:39:16)
    at Socket.<anonymous> (/home/ubuntu/public/server/node_modules/mysql/lib/Connection.js:82:28)
    at Socket.EventEmitter.emit (events.js:95:17)
    at Socket.<anonymous> (_stream_readable.js:746:14)

奇怪的是,当我尝试在 MySQL CLI 中执行这些命令时,它完美运行:

mysql> show tables;
Empty set (0.00 sec)

mysql> CREATE TABLE IF NOT EXISTS `groups` (`id` INTEGER NOT NULL auto_increment , `groupname` VARCHAR(255), `groupkey` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB; CREATE TABLE IF NOT EXISTS `users` (`id` INTEGER NOT NULL auto_increment , `username` VARCHAR(255) UNIQUE, `password` VARCHAR(255), `salt` VARCHAR(255), `token` VARCHAR(255), `group_id` INTEGER, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`), FOREIGN KEY (`group_id`) REFERENCES `groups` (`id`)) ENGINE=InnoDB; CREATE TABLE IF NOT EXISTS `messages` (`id` INTEGER NOT NULL auto_increment , `message` VARCHAR(255), `group_id` INTEGER, `user_id` INTEGER, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`), FOREIGN KEY (`group_id`) REFERENCES `groups` (`id`), FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)) ENGINE=InnoDB;
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.01 sec)

我是这样定义表格的:

var dbconfig = {};
dbconfig.database = process.env.database || 'crew';
dbconfig.username = process.env.username || 'root';
dbconfig.password = process.env.password || '';
dbconfig.hostname = process.env.hostname || 'localhost';

var sequelize = new Sequelize(dbconfig.database, dbconfig.username, dbconfig.password, {
  host: dbconfig.hostname
});

var User = sequelize.define('users', {
  username: {
    type: Sequelize.STRING, 
    unique: true
  },
  password: Sequelize.STRING,
  salt: Sequelize.STRING,
  token: Sequelize.STRING,
  group_id: {
    type: Sequelize.INTEGER,
    references: 'groups',
    referencesKey: 'id'
  }
});

var Message = sequelize.define('message', {
  message: Sequelize.STRING,
  group_id: {
    type: Sequelize.INTEGER,
    references: 'groups',
    referencesKey: 'id'
  },
  user_id: {
    type: Sequelize.INTEGER,
    references: 'users',
    referencesKey: 'id'
  }
});

var Group = sequelize.define('groups', {
  groupname: Sequelize.STRING,
  groupkey: Sequelize.STRING
});


Group.sync({force: true});
User.sync({force: true});
Message.sync({force: true});

想通了!!希望这会对其他人有所帮助。

所以基本上下面的命令是异步操作,它们在不同的时间执行,导致 sequelize 失败,因为表依赖于其他表,执行顺序很重要。

Group.sync({force: true});
User.sync({force: true});
Message.sync({force: true});

如果您不执行上述操作,而是在 sequelize 上调用 sync(),sequelize 会确切知道命令需要按什么顺序执行。

sequelize.sync();
const sequelize = new Sequelize(database, user, password, {
  host,
  port,
  dialect: "postgres",
  logging: false,
  sync: true, //create the table if it not exists
});