编译Mongoose后无法覆盖模型

Ana*_*ued 80 model mongoose mongodb node.js express

不确定我做错了什么,这是我的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 })
    });
Run Code Online (Sandbox Code Playgroud)

这是我的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); 
   });
Run Code Online (Sandbox Code Playgroud)

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

编译后无法覆盖'用户'模型.

我知道这个错误是由于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 
  } 
>
Run Code Online (Sandbox Code Playgroud)

jon*_*nie 147

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

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

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

  • 这确实是一个非常棘手的问题 - 我认为它是特定于操作系统的(它应该只在Mac和Windows上发生,因为FS忽略了这种情况).我有这个问题,但幸运的是看到了你的答案:)非常感谢Jonnie! (6认同)
  • 这个问题发生在我的OS X系统中. (4认同)

tht*_*gma 94

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

例如:

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);          
Run Code Online (Sandbox Code Playgroud)

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 
  })
});
Run Code Online (Sandbox Code Playgroud)

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); 
});
Run Code Online (Sandbox Code Playgroud)

  • 避免导出/需要模型 - 如果有任何模型可以导致其他模型,这可能导致依赖性的噩梦.使用`var User = mongoose.model('user')`而不是`require`. (55认同)
  • @wprl 你能进一步解释一下吗?为什么要求它会产生问题? (3认同)
  • 这个答案具有误导性。事实是,如果只有一个 mongoDB 服务器实例和多个数据库,如果您在另一个应用程序中定义已占用的数据库,则会出现此类错误。就这么简单 (3认同)

小智 39

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

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

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

let users = mongoose.model('users')
Run Code Online (Sandbox Code Playgroud)

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

let users
try {
  users = mongoose.model('users')
} catch (error) {
  users = mongoose.model('users', <UsersSchema...>)
}
Run Code Online (Sandbox Code Playgroud)

  • 2021 年更新:`导出默认 mongoose.models["user"] ?? mongoose.model(“用户”,模式)` (2认同)

Zep*_*ies 33

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

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

import mongoose from 'mongoose';
import user from './schemas/user';

export const User = mongoose.models.User || mongoose.model('User', user);
Run Code Online (Sandbox Code Playgroud)

  • 糟糕的`mongoose.models`不存在,至少在最近的版本中是这样 (3认同)
  • 我遇到了同样的问题,但通过在所有测试之前清除所有模型来修复它:`for (let model in mongoose.models) delete mongoose.models[model]` (3认同)
  • 这个答案帮助我修复了当我在代码中进行更改时的错误,然后 hmr 重新加载页面并出现错误“错误 - OverwriteModelError:编译后无法覆盖‘品牌’模型。”。 (3认同)
  • 在最新版本的 Mongoose 中使用它,看起来效果很好! (2认同)

小智 20

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

serverless offline --skipCacheInvalidation
Run Code Online (Sandbox Code Playgroud)

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

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

  • 我发现跳过缓存失效,不断重新加载很烦人,而是这样工作`module.exports = mongoose.models.Users || mongoose.model('Users', UsersSchema);` (4认同)
  • 很有帮助.谢谢. (2认同)

Jul*_*ian 15

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

module.exports = mongoose.models.Users || mongoose.model('Users', UsersSchema);
Run Code Online (Sandbox Code Playgroud)

  • 这就是我一直在寻找的、用于 Next.js 的确切答案。我希望这位于页面的更高位置! (5认同)
  • 我从来没有遇到过这个问题,直到我在 Next.js 中尝试 mongoose 时才出现这个问题。这个解决方案对我有用,谢谢!我认为 Next.js 中发生了这种情况,因为他们的开发模式是如何配置的。也许 Next.js 团队可以改进这一点...... (2认同)

Jam*_*ton 14

如果你在这里做到了,你可能会遇到同样的问题.我的问题是我正在定义另一个具有相同名称的模型.我打电话给我的画廊和我的文件模型"文件".你复制粘贴了!


小智 14

点击这里!官方示例。最重要的!事情是这样导出的

export default mongoose.models.Item || mongoose.model('Item', itemsSchema)
Run Code Online (Sandbox Code Playgroud)


小智 8

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

import User from '../myuser/User.js';
Run Code Online (Sandbox Code Playgroud)

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


小智 7

要解决此问题,请在创建模型之前检查模型是否存在:

if (!mongoose.models[entityDBName]) {
  return mongoose.model(entityDBName, entitySchema);
}
else {
  return mongoose.models[entityDBName];
}
Run Code Online (Sandbox Code Playgroud)


Tou*_*fiq 6

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

mongoose.models = {}
Run Code Online (Sandbox Code Playgroud)

前行:

mongoose.model(<MODEL_NAME>, <MODEL_SCHEMA>)
Run Code Online (Sandbox Code Playgroud)

希望它能解决您的问题


Moo*_*ure 5

我知道有一个可接受的解决方案,但我觉得当前的解决方案会产生很多样板文件,以便您可以测试模型。我的解决方案本质上是将您的模型放入一个函数中,如果模型尚未注册,则返回新模型,但如果已注册,则返回现有模型。

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()
Run Code Online (Sandbox Code Playgroud)

到处打开和关闭连接令人沮丧并且不能很好地压缩。

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


小智 5

这可能会对某些人造成打击,但我也遇到了错误,并意识到我只是在导入时拼错了用户模型。

错误:const User = require('./UserModel'); 正确:const User = require('./userModel');

难以置信,但考虑一下。


Jac*_*ack 5

这是发生这种情况的另一个原因。也许这可以帮助别人。请注意会员与会员之间的区别。他们一定是同一个人...

export default mongoose.models.Members || mongoose.model('Member', FamilySchema)
Run Code Online (Sandbox Code Playgroud)

改成:

export default mongoose.models.Member || mongoose.model('Member', FamilySchema)
Run Code Online (Sandbox Code Playgroud)