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

使用Express+Sequelize+TypeScript创建模型后返回空数组问题

我来帮你捋捋这个问题——你用Express+Sequelize+TypeScript建了模型,但require('../models')返回的models是空对象,这种情况大多是模型加载或Sequelize初始化的环节出了问题,咱们一步步排查解决:

可能的原因及对应解决方案

1. 单个模型的导出/注册方式错误

TypeScript里的模块导出和CommonJS的require经常会有适配问题,而且模型必须正确注册到Sequelize实例上才能被识别。

  • 确保每个模型文件都以“接收Sequelize实例并返回模型”的方式导出,比如:
// models/User.ts
import { DataTypes, Model, Sequelize } from 'sequelize';

// 导出一个函数,接收sequelize实例并定义模型
export default (sequelize: Sequelize) => {
  class User extends Model {
    public id!: number;
    public name!: string;
  }

  User.init(
    {
      id: {
        type: DataTypes.INTEGER,
        autoIncrement: true,
        primaryKey: true,
      },
      name: {
        type: DataTypes.STRING,
        allowNull: false,
      },
    },
    {
      sequelize, // 关联到传入的Sequelize实例
      modelName: 'User', // 这个名称会成为models对象里的键,必须设置
    }
  );

  return User;
};

2. 模型索引文件(models/index.ts)配置失误

这是最容易出问题的地方——你需要在index文件里初始化Sequelize,然后批量加载所有模型并注册到实例中。

正确的index.ts示例:

// models/index.ts
import { Sequelize } from 'sequelize';
import fs from 'fs';
import path from 'path';

// 初始化Sequelize实例
const sequelize = new Sequelize({
  dialect: 'postgres',
  host: '127.0.0.1',
  // 补充你的数据库名称、用户名、密码等配置
});

const models: Record<string, any> = {};

// 读取当前目录下所有模型文件(排除index.ts本身)
const modelFiles = fs.readdirSync(__dirname).filter(file => 
  file !== 'index.ts' && file.endsWith('.ts')
);

// 逐个加载并注册模型
for (const file of modelFiles) {
  const modelPath = path.join(__dirname, file);
  // 注意:如果用ES模块导出,要通过.default获取导出的函数
  const modelFactory = require(modelPath).default;
  const model = modelFactory(sequelize);
  // 用模型的name属性作为键存入models对象
  models[model.name] = model;
}

// 处理模型间的关联(如果有的话)
Object.keys(models).forEach(modelName => {
  if (models[modelName].associate) {
    models[modelName].associate(models);
  }
});

// 同时支持ES模块和CommonJS导入
export { sequelize, models };
module.exports = { sequelize, models };

这里要注意:如果你的TypeScript配置是module: ESNext,但运行时用的是CommonJS(比如编译后的js文件),一定要确保模型的导出能被require正确识别——上面的代码里用require(modelPath).default就是为了适配ES模块的export default。

3. 检查require的路径是否正确

你调用require('../models')时,要确认相对路径是否匹配项目结构。比如如果你的代码在src/routes/user.ts,而models文件夹在src/models,那../models是正确的;但如果你的代码在src/controllers/user.ts,可能需要../models或者../../models,路径错了会加载到错误的文件,自然得不到正确的模型。

4. TypeScript编译后的文件路径问题

如果你的项目是先编译TS到dist目录再运行,那要确保require的路径指向dist/models,而不是源码的src/models——Node.js无法直接运行.ts文件(除非用ts-node),如果加载到未编译的.ts文件,很可能无法正确解析模型。

5. 验证模型是否被成功加载

可以在models/index.ts里加一行日志,比如:

console.log('已加载的模型:', Object.keys(models));

运行项目后看看控制台输出,如果这里是空数组,说明模型文件没被正确读取——检查下模型文件名是否符合过滤规则(比如是不是用了.js后缀,或者文件名大小写和代码里的不一致)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:11:26