Sequelizeでテーブル作成時のエラー
前提
docker-composeで立てたMySQLのコンテナとNode.jsによるAPIコンテナがある。
接続の確認自体は済んでいるものとする。
https://sequelize.org/docs/v6/getting-started/#testing-the-connection
APIコンテナからSequelizeを用いて
Model.sync({force: true});
でテーブルを作成しようとした際にエラーが発生。
todo-api | Executing (default): CREATE TABLE IF NOT EXISTS `Tasks` (`id` INTEGER NOT NULL auto_increment , `name` VARCHAR(255) NOT NULL, `completed` TINYINT(1) NOT NULL, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
todo-api | node:internal/process/promises:288
todo-api | triggerUncaughtException(err, true /* fromPromise */);
todo-api | ^
todo-api |
todo-api | Error
todo-api | at Query.run (/home/node/node_modules/sequelize/lib/dialects/mysql/query.js:52:25)
todo-api | at /home/node/node_modules/sequelize/lib/sequelize.js:314:28
todo-api | at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
todo-api | at async MySQLQueryInterface.createTable (/home/node/node_modules/sequelize/lib/dialects/abstract/query-interface.js:98:12)
todo-api | at async Task.sync (/home/node/node_modules/sequelize/lib/model.js:942:7)
todo-api | at async /home/node/models/tasks.js:20:5 {
todo-api | name: 'SequelizeDatabaseError',
todo-api | parent: Error: Table 'todo.tasks' doesn't exist
todo-api | at Packet.asError (/home/node/node_modules/mysql2/lib/packets/packet.js:728:17)
todo-api | at Query.execute (/home/node/node_modules/mysql2/lib/commands/command.js:29:26)
todo-api | at Connection.handlePacket (/home/node/node_modules/mysql2/lib/connection.js:488:32)
todo-api | at PacketParser.onPacket (/home/node/node_modules/mysql2/lib/connection.js:94:12)
todo-api | at PacketParser.executeStart (/home/node/node_modules/mysql2/lib/packet_parser.js:75:16)
todo-api | at Socket.<anonymous> (/home/node/node_modules/mysql2/lib/connection.js:101:25)
todo-api | at Socket.emit (node:events:513:28)
todo-api | at addChunk (node:internal/streams/readable:324:12)
todo-api | at readableAddChunk (node:internal/streams/readable:297:9)
todo-api | at Readable.push (node:internal/streams/readable:234:10) {
todo-api | code: 'ER_NO_SUCH_TABLE',
todo-api | errno: 1146,
todo-api | sqlState: '42S02',
todo-api | sqlMessage: "Table 'todo.tasks' doesn't exist",
todo-api | sql: 'CREATE TABLE IF NOT EXISTS `Tasks` (`id` INTEGER NOT NULL auto_increment , `name` VARCHAR(255) NOT NULL, `completed` TINYINT(1) NOT NULL, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;',
todo-api | parameters: undefined
todo-api | },
todo-api | original: Error: Table 'todo.tasks' doesn't exist
todo-api | at Packet.asError (/home/node/node_modules/mysql2/lib/packets/packet.js:728:17)
todo-api | at Query.execute (/home/node/node_modules/mysql2/lib/commands/command.js:29:26)
todo-api | at Connection.handlePacket (/home/node/node_modules/mysql2/lib/connection.js:488:32)
todo-api | at PacketParser.onPacket (/home/node/node_modules/mysql2/lib/connection.js:94:12)
todo-api | at PacketParser.executeStart (/home/node/node_modules/mysql2/lib/packet_parser.js:75:16)
todo-api | at Socket.<anonymous> (/home/node/node_modules/mysql2/lib/connection.js:101:25)
todo-api | at Socket.emit (node:events:513:28)
todo-api | at addChunk (node:internal/streams/readable:324:12)
todo-api | at readableAddChunk (node:internal/streams/readable:297:9)
todo-api | at Readable.push (node:internal/streams/readable:234:10) {
todo-api | code: 'ER_NO_SUCH_TABLE',
todo-api | errno: 1146,
todo-api | sqlState: '42S02',
todo-api | sqlMessage: "Table 'todo.tasks' doesn't exist",
todo-api | sql: 'CREATE TABLE IF NOT EXISTS `Tasks` (`id` INTEGER NOT NULL auto_increment , `name` VARCHAR(255) NOT NULL, `completed` TINYINT(1) NOT NULL, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;',
todo-api | parameters: undefined
todo-api | },
todo-api | sql: 'CREATE TABLE IF NOT EXISTS `Tasks` (`id` INTEGER NOT NULL auto_increment , `name` VARCHAR(255) NOT NULL, `completed` TINYINT(1) NOT NULL, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;',
todo-api | parameters: {}
todo-api | }
確認したこと
エラーを見ると今からデータベースのテーブルを作成する関数を実行しようとしているのにテーブルがないと言われている。
todo.tasks doesn't existはtodoというデータベースの中のtasksというテーブルはないということ。
君はそのtasksを作るための関数ではないのか...?
解決策
原因はわかっていないが、Modelの定義の際にテーブル名を明示することでテーブルを作成することができた。
const Task = sequelize.define('Task', {
name: {
type: DataTypes.STRING,
allowNull: false
},
completed: {
type: DataTypes.BOOLEAN,
allowNull: false
}
},{
tableName: "tasks"
});
Sequelizeには予測機能のようなものがあり、
sequelize.defineで定義した'Task'というものからテーブル名はこれを複数形にしたtasksが自動的にテーブル名として設定される。これを明示しただけなのだがエラーが出なくなった。
補足
これを確認したのちにテーブルを一度削除。テーブル名を設定する
},{
tableName: "tasks"
});
の記述を消して再度実行してみると普通に動作した。原因は完全にわかっていないがMySQL側の問題ぽい?