Sequelize多Schema实例被覆盖求助:仅保留单个实例
问题排查与解决
核心原因
大概率是你加载superadmin目录模型的逻辑,不小心覆盖了db对象中存储tenants实例的属性键。常见场景:
- 加载模型时未给两个实例的模型划分独立命名空间,直接将模型挂载到
db根对象,而非db.tenants和db.superadmin子对象下 - 初始化模型时,错误地将
superadmin的Sequelize实例赋值给了和tenants实例相同的键名
修正步骤
先看典型的错误逻辑示例:
const { Sequelize } = require('sequelize'); const fs = require('fs'); // 创建两个实例 const tenantsSequelize = new Sequelize(/* tenants配置 */); const superadminSequelize = new Sequelize(/* superadmin配置 */); const db = {}; db.sequelize = tenantsSequelize; // 先存入tenants实例 // 加载tenants模型 fs.readdirSync('./models/tenants') .filter(file => file !== 'index.js') .forEach(file => { const model = require(`./tenants/${file}`)(tenantsSequelize, Sequelize.DataTypes); db[model.name] = model; }); // 此处直接覆盖了db.sequelize db.sequelize = superadminSequelize; // 加载superadmin模型时,若模型名和tenants重复也会覆盖 fs.readdirSync('./models/superadmin') .filter(file => file !== 'index.js') .forEach(file => { const model = require(`./superadmin/${file}`)(superadminSequelize, Sequelize.DataTypes); db[model.name] = model; });
改成给两个实例划分独立命名空间的结构:
const { Sequelize } = require('sequelize'); const fs = require('fs'); const path = require('path'); // 初始化两个独立的Sequelize实例 const tenantsDB = new Sequelize(/* tenants的数据库配置 */); const superadminDB = new Sequelize(/* superadmin的数据库配置 */); // 给两个实例创建独立的存储结构 const db = { tenants: { sequelize: tenantsDB, models: {} }, superadmin: { sequelize: superadminDB, models: {} } }; // 加载tenants目录下的模型 const tenantsModelDir = path.join(__dirname, 'tenants'); fs.readdirSync(tenantsModelDir) .filter(file => file.endsWith('.js') && file !== 'index.js') .forEach(file => { const model = require(path.join(tenantsModelDir, file))(tenantsDB, Sequelize.DataTypes); db.tenants.models[model.name] = model; }); // 加载superadmin目录下的模型 const superadminModelDir = path.join(__dirname, 'superadmin'); fs.readdirSync(superadminModelDir) .filter(file => file.endsWith('.js') && file !== 'index.js') .forEach(file => { const model = require(path.join(superadminModelDir, file))(superadminDB, Sequelize.DataTypes); db.superadmin.models[model.name] = model; }); // 若模型有关联逻辑,分别处理 // Object.values(db.tenants.models).forEach(model => model.associate && model.associate(db.tenants.models)); // Object.values(db.superadmin.models).forEach(model => model.associate && model.associate(db.superadmin.models)); module.exports = db;
额外注意事项
- 后续调用模型时,通过
db.tenants.models.User或db.superadmin.models.Role的方式访问,避免混淆 - 即使两个目录下模型名重复,因为在独立命名空间中也不会互相覆盖
内容的提问来源于stack exchange,提问作者Mohammed Saber
相关产品推荐
相关产品推荐

