如何将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
相关产品推荐
相关产品推荐

