执行Sequelize CLI迁移时遇配置找不到及未定义属性读取错误求助
运行npx sequelize-cli db:migrate时出现以下错误:
Sequelize CLI [Node: 18.9.1, CLI: 6.5.1, ORM: 6.20.1]
ERROR: Cannot find "/src/db/migrations/config/config.json". Have you run "sequelize init"?
ERROR: Cannot read properties of undefined (reading 'detail')
sequelize-cli db:migrateRun pending migrations
已执行过sequelize init,即使将config改为json格式仍报错,相关配置文件如下:
config.js文件
import dotenv from "dotenv"; dotenv.config(); export default { development: { username: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, host: process.env.DB_HOST, port: process.env.DB_PORT, dialect: process.env.DB_DIALECT, logging: true, }, test: { username: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, host: process.env.DB_HOST, dialect: process.env.DB_DIALECT, }, production: { username: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, host: process.env.DB_HOST, dialect: process.env.DB_DIALECT, }, };
迁移文件
"use strict"; /** @type {import('sequelize-cli').Migration} */ module.exports = { async up(queryInterface, Sequelize) { await queryInterface.createTable("Users", { id: { type: Sequelize.INTEGER, allowNull: false, autoIncrement: true, primaryKey: true, }, name: { type: Sequelize.STRING(50), allowNull: false, }, birth_date: { type: Sequelize.DATEONLY, allowNull: false, }, email: { type: Sequelize.STRING(62), allowNull: false, }, phone: { type: Sequelize.STRING(20), allowNull: false, }, address: { type: Sequelize.STRING(100), allowNull: false, }, password: { type: Sequelize.STRING(100), allowNull: false, }, position_id: { type: Sequelize.INTEGER, allowNull: false, references: { model: "Position", key: "id", }, }, is_active: { type: Sequelize.BOOLEAN, allowNull: false, }, is_admin: { type: Sequelize.BOOLEAN, allowNull: false, }, created_at: { type: Sequelize.DATE, allowNull: false, }, updated_at: { type: Sequelize.DATE, allowNull: false, }, }); }, async down(queryInterface, Sequelize) { await queryInterface.dropTable("Users"); }, };
.sequelizerc文件
import path from "path"; export default { config: path.resolve("config", "config.js"), };
package.json文件
{ "name": "startbootstrap-sb-admin-2-gh-pages", "version": "1.0.0", "description": "", "main": "gulpfile.js", "scripts": { "test": "test", "dev": "nodemon src/server.js" }, "type": "module", "author": "", "license": "ISC", "dependencies": { "connect-flash": "^0.1.1", "cookie-parser": "^1.4.6", "dotenv": "^16.0.3", "ejs": "^3.1.8", "express": "^4.18.1", "express-ejs-layouts": "^2.5.1", "express-session": "^1.17.3", "http": "^0.0.1-security", "http-error": "^0.0.6", "morgan": "^1.10.0", "mysql2": "^2.3.3", "nodemon": "^2.0.16", "path": "^0.12.7", "sequelize": "^6.20.1" }, "devDependencies": { "sequelize-cli": "^6.5.1" } }
问题根源
项目启用了ES模块(package.json中type: module),但Sequelize CLI对ES模块的支持有限,默认以CommonJS规则加载配置,加上.sequelizerc路径配置不完整,导致CLI无法定位正确的配置文件。
解决步骤
1. 修正.sequelizerc为CommonJS格式
Sequelize CLI目前无法直接识别ES模块语法的配置文件,改为CommonJS:
const path = require('path'); module.exports = { config: path.resolve(__dirname, 'config', 'config.js'), migrations: path.resolve(__dirname, 'src', 'db', 'migrations'), models: path.resolve(__dirname, 'src', 'db', 'models'), seeders: path.resolve(__dirname, 'src', 'db', 'seeders') };
明确指定所有核心目录路径,避免CLI使用默认路径出错
2. 调整config.js为CommonJS导出
将ES模块的export default改为CommonJS的module.exports:
require('dotenv').config(); module.exports = { development: { username: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, host: process.env.DB_HOST, port: process.env.DB_PORT, dialect: process.env.DB_DIALECT, logging: true, }, test: { username: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, host: process.env.DB_HOST, dialect: process.env.DB_DIALECT, }, production: { username: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, host: process.env.DB_HOST, dialect: process.env.DB_DIALECT, }, };
3. 验证环境变量配置
确保根目录下存在.env文件,且包含完整的数据库连接信息:
DB_USER=你的数据库用户名 DB_PASSWORD=你的数据库密码 DB_NAME=你的数据库名称 DB_HOST=localhost DB_PORT=3306 DB_DIALECT=mysql
4. 检查外键依赖
迁移文件中Users表依赖Position表的外键,需确保Position表已提前完成迁移,或调整迁移文件的执行顺序(将Position的迁移文件命名前缀设为更小的数字)。
5. 重新执行迁移命令
在项目根目录运行:
npx sequelize-cli db:migrate
额外排查点
- 确认数据库服务已正常启动,且
.env中的配置能成功连接数据库 - 检查项目目录结构是否与
.sequelizerc中指定的路径完全匹配 - 若仍报错,尝试删除
node_modules和package-lock.json,重新执行npm install后再试
内容的提问来源于stack exchange,提问作者dev user

