You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node ESM模块搭配Sequelize v6初始化报错:sequelize.import不是函数

解决Sequelize v6 ESM环境下替代sequelize.import的问题

Sequelize v6已移除sequelize.import方法,传统require加载方案无法适配ESM模块系统,以下是针对你的代码的具体改造方案:

1. 统一模型文件的导出格式

确保所有模型文件(如User.js、Message.js)采用ESM默认导出,格式示例:

// models/User.js示例
export default (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    username: {
      type: DataTypes.STRING,
      allowNull: false
    }
    // 其他字段定义
  });

  User.associate = (db) => {
    User.hasMany(db.Message); // 关联关系定义
  };

  return User;
};

2. 改造models/index.js的模型加载逻辑

由于ESM的import()是异步操作,需要将syncDb改为异步函数,替换同步forEach为支持await的循环:

import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import Sequelize from 'sequelize';
import process from 'process';
const env = process.env.NODE_ENV || 'development';
import configDB from '../config/config.json' assert { type: "json" };
const config = configDB[env];
const db = {};
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const basename = path.basename(__filename);

// 改为异步函数
export default async function syncDb() {
let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config);
}

// 筛选模型文件列表
const modelFiles = fs
  .readdirSync(__dirname)
  .filter(file => {
    return (
      file.indexOf('.') !== 0 &&
      file !== basename &&
      file.slice(-3) === '.js' &&
      file.indexOf('.test.js') === -1
    );
  });

// 用for...of循环替代forEach,支持await异步加载
for (const file of modelFiles) {
  const modelModule = await import(path.join(__dirname, file));
  const model = modelModule.default(sequelize, Sequelize.DataTypes);
  db[model.name] = model;
}

// 执行模型关联
Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

// 异步验证数据库连接
try {
  await db.sequelize.authenticate();
  console.log('Database connected!!');
} catch (err) {
  console.error('Database connection failed:', err);
}

// 如需自动同步模型结构,可添加该行
// await db.sequelize.sync();

return db;
}

3. 调整Server.js的调用逻辑

syncDb变为异步函数后,需用await调用,并将启动逻辑包裹在async函数中:

import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
import syncDb from './models/index.js';

async function startServer() {
  // 等待数据库初始化完成
  await syncDb();

  // GraphQL schema定义
  const typeDefs = `#graphql
    type Query {
      hello: String
    }
  `;

  // 解析器定义
  const resolvers = {
    Query: {
      hello: () => 'world',
    },
  };

  const server = new ApolloServer({
    typeDefs,
    resolvers,
  });

  const { url } = await startStandaloneServer(server);
  console.log(`🚀 Server ready at ${url}`);
}

// 启动服务并捕获错误
startServer().catch(err => console.error('Server startup error:', err));

核心逻辑说明

  • 用ESM动态import()替代废弃的sequelize.import,实现异步加载模型模块
  • 模型文件保持接收sequelize和DataTypes的函数格式,与原逻辑兼容
  • 改用for...of循环遍历文件,解决forEach无法处理异步await的问题

内容的提问来源于stack exchange,提问作者PhilibertEtienne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 23:03:06