首页 文章

编译Mongoose后无法覆盖模型

提问于
浏览
56

不确定我做错了什么,这是我的check.js

var db = mongoose.createConnection('localhost', 'event-db');
db.on('error', console.error.bind(console, 'connection error:'));

var a1= db.once('open',function(){
var user = mongoose.model('users',{ 
       name:String,
       email:String,
       password:String,
       phone:Number,
      _enabled:Boolean
     });

user.find({},{},function (err, users) {
    mongoose.connection.close();
    console.log("Username supplied"+username);
    //doSomethingHere })
    });

这是我的insert.js

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/event-db')

var user = mongoose.model('users',{
     name:String,
     email:String,
     password: String,
     phone:Number,
     _enabled:Boolean
   });

var new_user = new user({
     name:req.body.name,
     email: req.body.email,
     password: req.body.password,
     phone: req.body.phone,
     _enabled:false
   });

new_user.save(function(err){
    if(err) console.log(err); 
   });

每当我试图运行check.js时,我都会收到此错误

Cannot overwrite 'users' model once compiled .

我知道这个错误是由于Schema不匹配造成的,但我看不出这是怎么回事?我对mongoose和nodeJS很新 .

以下是我从MongoDB的客户端界面获取的内容:

MongoDB shell version: 2.4.6 connecting to: test 
> use event-db 
  switched to db event-db 
> db.users.find() 
  { "_id" : ObjectId("52457d8718f83293205aaa95"), 
    "name" : "MyName", 
    "email" : "myemail@me.com", 
    "password" : "myPassword", 
    "phone" : 900001123, 
    "_enable" : true 
  } 
>

17 回答

  • 0

    我有一种情况,我必须动态地为每个请求创建模型,因此我收到此错误,但是,我用来修复它的方法是使用deleteModel方法,如下所示:

    var contentType = 'Product'
    
    var contentSchema = new mongoose.Schema(schema, virtuals);
    
    var model = mongoose.model(contentType, contentSchema);
    
    mongoose.deleteModel(contentType);
    

    我希望这可以帮助任何人 .

  • 75

    当我这样写时,这发生在我身上:

    import User from '../myuser/User.js';
    

    但是,真正的路径是'../myUser/User.js'

  • 11

    如果您定义具有相同集合名称的2个不同架构可能会发生此问题

  • -4
    If you want to overwrite the existing class for different collection using typescript
    then you have to inherit the existing class from different class.
    
    export class User extends Typegoose{
      @prop
      username?:string
      password?:string
    }
    
    
    export class newUser extends User{
        constructor() {
            super();
        }
    }
    
    export const UserModel = new User ().getModelForClass(User , { schemaOptions: { collection: "collection1" } });
    
    export const newUserModel = new newUser ().getModelForClass(newUser , { schemaOptions: { collection: "collection2" } });
    
  • 115

    “观察”测试时我遇到了这个问题 . 编辑测试后, Watch 会重新进行测试,但由于这个原因导致测试失败 .

    我通过检查模型是否存在然后使用它来修复它,否则创建它 .

    import mongoose from 'mongoose';
    import user from './schemas/user';
    
    export const User = mongoose.models.User || mongoose.model('User', user);
    
  • 2

    我知道有一个公认的解决方案,但我觉得当前的解决方案会产生很多样板,以便您可以测试模型 . 我的解决方案主要是将模型放在函数内部,如果模型尚未注册则返回新模型,如果模型已经返回,则返回现有模型 .

    function getDemo () {
      // Create your Schema
      const DemoSchema = new mongoose.Schema({
        name: String,
        email: String
      }, {
        collection: 'demo'
      })
      // Check to see if the model has been registered with mongoose
      // if it exists return that model
      if (mongoose.models && mongoose.models.Demo) return mongoose.models.Demo
      // if no current model exists register and return new model
      return mongoose.model('Demo', DemoSchema)
    }
    
    export const Demo = getDemo()
    

    在整个地方打开和关闭连接令人沮丧,并且不能很好地压缩 .

    这样,如果我要求模型两个不同的地方或更具体地在我的测试中我不会得到错误并且返回所有正确的信息 .

  • 0

    如果您使用无服务器离线并且不想使用 --skipCacheInvalidation ,则可以很好地使用:

    module.exports = mongoose.models.Users || mongoose.model('Users', UsersSchema);
    
  • 0

    你可以轻松解决这个问题

    delete mongoose.connection.models['users'];
    const usersSchema = mongoose.Schema({...});
    export default mongoose.model('users', usersSchema);
    
  • 27

    如果您正在使用expressjs,则可能需要在app.get()之外移动模型定义,以便在实例化脚本时仅调用一次 .

  • 0

    单元测试时遇到了这个问题 .

    第一次调用模型创建函数时,mongoose将模型存储在您提供的密钥下(例如“用户”) . 如果您多次使用相同的键调用模型创建函数,则mongoose将不允许您覆盖现有模型 .

    你可以检查模型是否已经存在于mongoose中:

    let users = mongoose.model('users')
    

    如果模型不存在,这将抛出错误,因此您可以将其包装在try / catch中以获取模型或创建模型:

    let users
    try {
      users = mongoose.model('users')
    } catch (error) {
      users = mongoose.model('users', <UsersSchema...>)
    }
    
  • 0

    发生错误是因为您已经定义了架构,然后再次定义架构 . 通常,您应该做的是将模式实例化一次,然后让全局对象在需要时调用它 .

    例如:

    user_model.js

    var mongoose = require('mongoose');
    var Schema = mongoose.Schema;
    
    var userSchema = new Schema({
       name:String,
       email:String,
       password:String,
       phone:Number,
       _enabled:Boolean
    });
    module.exports = mongoose.model('users', userSchema);
    

    check.js

    var mongoose = require('mongoose');
    var User = require('./user_model.js');
    
    var db = mongoose.createConnection('localhost', 'event-db');
    db.on('error', console.error.bind(console, 'connection error:'));
    var a1= db.once('open',function(){
      User.find({},{},function (err, users) {
        mongoose.connection.close();
        console.log("Username supplied"+username);
        //doSomethingHere 
      })
    });
    

    insert.js

    var mongoose = require('mongoose');
    var User = require('./user_model.js');
    
    mongoose.connect('mongodb://localhost/event-db');
    var new_user = new User({
        name:req.body.name
      , email: req.body.email
      , password: req.body.password
      , phone: req.body.phone
      , _enabled:false 
    });
    new_user.save(function(err){
      if(err) console.log(err); 
    });
    
  • 22

    是因为您的架构已经在创建新架构之前进行验证 .

    var mongoose = require('mongoose');
    module.exports = function () {
    var db = require("../libs/db-connection")();
    //schema de mongoose
    var Schema = require("mongoose").Schema;
    
    var Task = Schema({
        field1: String,
        field2: String,
        field3: Number,
        field4: Boolean,
        field5: Date
    })
    
    if(mongoose.models && mongoose.models.tasks) return mongoose.models.tasks;
    
    return mongoose.model('tasks', Task);
    
  • 0

    因此,您可能会遇到此错误的另一个原因是,如果您在不同的文件中使用相同的模型,但您的 require 路径具有不同的情况 . 例如,在我的情况下,我有:

    require('./models/User') 在一个文件中,然后在另一个文件中我需要访问用户模型我有 require('./models/user') .

    我想查找模块和mongoose将它视为一个不同的文件 . 一旦我确定案件匹配,它就不再是一个问题 .

  • 3

    如果你在这里做到了,你可能会遇到同样的问题 . 我的问题是 i was defining another model with the same name . 我打电话给我的画廊和我的文件模型"File" . 你复制粘贴了!

  • 0

    我通过添加来解决这个问题

    mongoose.models = {}
    

    在线之前:

    mongoose.model(<MODEL_NAME>, <MODEL_SCHEMA>)
    

    希望它能解决你的问题

  • 15

    模式定义对于集合应该是唯一的,它不应该是集合的一个模式 .

  • 4

    我一直在遇到这个问题,这不是因为模式定义而是因为无服务器离线模式 - 我只是设法解决它:

    serverless offline --skipCacheInvalidation
    

    这里提到https://github.com/dherault/serverless-offline/issues/258

    希望这有助于在无服务器和运行脱机模式下构建项目的其他人 .

相关问题