Mongoose报错Cannot overwrite `users` model once compiled及架构疑问
解决Mongoose报错:无法覆盖已编译的
users模型 报错原因
Mongoose不允许重复编译同名模型。你的代码里每次调用UserModel.getInstance()都会执行initSchema(),重复调用mongoose.model("users", schema)创建模型;同时第二个UserModel的构造逻辑里,若模型未提前创建,DataAccess.getSchema直接调用mongoose.model("users")会报错,核心冲突点都是重复创建/编译模型。
修复方案
1. 修正第一个UserModel的重复创建问题
修改initSchema方法,先检查模型是否已存在,仅在不存在时创建:
class UserModel { initSchema() { // 检查模型是否已编译,避免重复创建 if (!mongoose.models["users"]) { const schema = new Schema({ name: "string", email: "string", password: "string", }); mongoose.model("users", schema); } } getInstance() { this.initSchema(); return mongoose.model("users"); } } export default UserModel;
2. 优化DataAccess与UserModel的模型传递逻辑
调整DataAccess,使其支持“获取已存在模型/传入Schema创建新模型”的逻辑,同时让UserModel主动传递模型名和Schema:
修正DataAccess类
class DataAccess { getSchema = (modelName: string, schema?: any) => { // 优先返回已存在的模型 if (mongoose.models[modelName]) { return mongoose.model(modelName); } // 若传入Schema则创建新模型,否则抛出错误 if (schema) { return mongoose.model(modelName, schema); } throw new Error(`模型${modelName}不存在且未提供Schema`); } }
修正UserModel类
import { Schema } from 'mongoose'; export class UserModel extends BaseModel { constructor() { const dataAccess = new DataAccess(); // 定义users表的Schema const userSchema = new Schema({ name: "string", email: "string", password: "string", }); // 传递模型名和Schema给DataAccess,获取模型实例 const model = dataAccess.getSchema("users", userSchema); super(model); } }
3. 在BaseService中使用模型名
若需要在BaseService中使用模型名,可以在BaseModel中保存模型名称,后续BaseService继承后直接调用:
class BaseModel { protected model: any; protected modelName: string; constructor(model: any) { this.model = model; // 从模型实例中获取名称 this.modelName = model.modelName; } } // BaseService示例 class BaseService extends BaseModel { async list() { console.log(`正在查询${this.modelName}数据`); return this.model.find(); } }
内容的提问来源于stack exchange,提问作者dmx
相关产品推荐
相关产品推荐

