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

如何将Sequelize模型按子目录拆分并调整加载逻辑实现分层调用

Sequelize 模型目录分层加载实现方案

你只需要修改models/index.js的文件读取逻辑为递归遍历,同时按子文件夹名称生成分层挂载结构即可,以下是完整可直接使用的代码:

"use strict"

const fs = require("fs")
const path = require("path")
const Sequelize = require("sequelize")
const basename = path.basename(__filename)
const env = process.env.NODE_ENV || "development"
const envConfigs = require("../config/config")
const config = envConfigs[env]
const db = {}

let sequelize
if (config.url) {
  sequelize = new Sequelize(config.url, config)
} else {
  sequelize = new Sequelize(
    config.database,
    config.username,
    config.password,
    config
  )
}

// 递归遍历目录加载模型
function loadModels(dir, parentNamespace = db) {
  const files = fs.readdirSync(dir)
  files.forEach(file => {
    const fullPath = path.join(dir, file)
    const stat = fs.statSync(fullPath)
    // 如果是目录,创建命名空间后递归遍历
    if (stat.isDirectory()) {
      // 文件夹名作为命名空间键名,不存在则初始化
      const namespace = file.toLowerCase()
      if (!parentNamespace[namespace]) {
        parentNamespace[namespace] = {}
      }
      loadModels(fullPath, parentNamespace[namespace])
      return
    }
    // 过滤非js文件、index.js自身、隐藏文件
    if (
      file.indexOf(".") === 0 
      || fullPath === __filename 
      || file.slice(-3) !== ".js"
    ) {
      return
    }
    // 加载模型
    const model = require(fullPath)(sequelize, Sequelize.DataTypes)
    // 模型名小写作为键名,挂载到当前父命名空间下
    const modelKey = model.name.toLowerCase()
    parentNamespace[modelKey] = model
    // 兼容原有写法,同时挂载到db根节点,不需要可删除下一行
    db[model.name] = model
  })
}

// 从当前models目录开始遍历
loadModels(__dirname)

// 执行关联逻辑,遍历所有层级的模型
function associateAll(namespace = db) {
  Object.values(namespace).forEach(item => {
    if (typeof item === 'object' && item.associate) {
      item.associate(db)
    } else if (typeof item === 'object' && !item.sequelize) {
      // 是命名空间对象,递归遍历
      associateAll(item)
    }
  })
}

associateAll()

db.sequelize = sequelize
module.exports = db

使用说明

  • 调用方式完全符合你的需求,引入后即可通过分层路径访问模型:
    const db = require("../../models")
    // 分层调用
    const User = db.settings.user
    const Product = db.stock.products
    // 兼容原有根节点调用方式,不需要可以删除代码中对应挂载逻辑
    const User = db.User
    
  • 模型关联写法保持一致,在模型的associate方法中可直接访问整个db对象的所有层级模型:
    // settings/user.js 中的关联示例
    associate: (db) => {
      db.settings.user.hasMany(db.stock.stock, {
        foreignKey: 'create_user_id',
        as: 'createdStocks'
      })
    }
    

注意事项

如果不需要兼容原有根节点挂载模型的写法,直接删除loadModels函数中// 兼容原有写法注释下方的db[model.name] = model行即可。

内容的提问来源于stack exchange,提问作者Gianfranco Depaoli Gampel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 00:15:03