Подтвердить что ты не робот

Невозможно перезаписать модель после компиляции Mongoose

Не уверен, что я делаю неправильно, вот мой 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, я получаю эту ошибку

Невозможно перезаписать модель пользователя после компиляции.

Я понимаю, что эта ошибка возникает из-за несоответствия Схемы, но я не вижу, где это происходит? Я новичок в 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" : "[email protected]", 
    "password" : "myPassword", 
    "phone" : 900001123, 
    "_enable" : true 
  } 
>
4b9b3361

Ответ 1

Ошибка возникает из-за того, что у вас уже определена схема, а затем вы снова определяете схему. Как правило, вам нужно создать экземпляр схемы один раз, а затем глобальный объект вызовет его, когда ему это нужно.

Например:

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); 
});

Ответ 2

Итак, другой причиной, по которой вы можете получить эту ошибку, является то, что вы используете одну и ту же модель в разных файлах, но ваш путь require имеет другой случай. Например, в моей ситуации я:

require('./models/User') в одном файле, а затем в другом файле, где мне нужен доступ к модели пользователя, у меня был require('./models/User').

Я предполагаю, что поиск модулей и mongoose рассматривает его как другой файл. Как только я убедился, что дело совпало с этим, это уже не проблема.

Ответ 3

У меня была эта проблема во время модульного тестирования.

При первом вызове функции создания модели mongoose сохраняет модель под ключом, который вы предоставляете (например, "пользователи" ). Если вы вызываете функцию создания модели с одним и тем же ключом более одного раза, mongoose не позволит вам перезаписать существующую модель.

Вы можете проверить, существует ли модель в мангусте с:

let users = mongoose.model('users')

Это вызовет ошибку, если модель не существует, поэтому вы можете обернуть ее в try/catch, чтобы либо получить модель, либо создать ее:

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

Ответ 4

У меня была эта проблема во время просмотра тестов. Когда тесты были отредактированы, часы повторно запускали тесты, но по этой причине они не сработали.

Я исправил это, проверив, существует ли модель, затем используйте ее, а затем создайте ее.

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

export const User = mongoose.models.User || mongoose.model('User', user);

Ответ 5

Я столкнулся с этой проблемой, и это было не из-за определений схемы, а из-за автономного режима без сервера - мне просто удалось решить эту проблему следующим образом:

serverless offline --skipCacheInvalidation

Который упоминается здесь https://github.com/dherault/serverless-offline/issues/258

Надеюсь, это поможет кому-то еще, кто строит свой проект на сервере и работает в автономном режиме.

Ответ 6

Если вы сделали это здесь, возможно, у вас была та же проблема, что и я. Моя проблема заключалась в том, что я определял другую модель с тем же именем. Я назвал свою галерею и мою файловую модель "Файл". Дарн вы копируете и вставляете!

Ответ 7

Если вы используете автономный сервер и не хотите использовать --skipCacheInvalidation, вы можете использовать:

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

Ответ 8

Это случилось со мной, когда я пишу так:

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

Однако истинным путем является "../myUser/User.js"

Ответ 9

Я знаю, что есть приемлемое решение, но я чувствую, что текущее решение приводит к большому количеству шаблонов, чтобы вы могли тестировать Модели. Мое решение состоит в том, чтобы взять модель и разместить ее внутри функции, что приведет к возврату новой модели, если модель не была зарегистрирована, но возвращает существующую модель, если она есть.

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()

Открытие и закрытие соединений повсеместно расстраивает и плохо сжимает.

Таким образом, если я должен был потребовать от модели два разных места или, более конкретно, в моих тестах, я бы не стал получать ошибки и возвращалась вся правильная информация.

Ответ 10

Я решил это, добавив

mongoose.models = {}

перед строкой:

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

Надеюсь, это решит вашу проблему

Ответ 11

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" } });

Ответ 12

Определение схемы должно быть уникальным для коллекции, оно не должно быть более одной схемы для коллекции.

Ответ 13

Эта проблема может возникнуть, если вы определяете 2 разные схемы с одним и тем же именем коллекции

Ответ 14

потому что ваша схема уже есть, проверьте, прежде чем создавать новую схему.

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);

Ответ 15

Вы можете легко решить это, выполнив

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

Ответ 16

У меня есть ситуация, когда я должен динамически создавать модель с каждым запросом, и из-за этого я получил эту ошибку, однако, что я использовал, чтобы исправить это, используя метод deleteModel, как показано ниже:

var contentType = 'Product'

var contentSchema = new mongoose.Schema(schema, virtuals);

var model = mongoose.model(contentType, contentSchema);

mongoose.deleteModel(contentType);

Я надеюсь, что это может кому-нибудь помочь.

Ответ 17

The reason of this issue is: 

you given the model name "users" in the line 
<<<var user = mongoose.model('users' {>>> in check.js file

and again the same model name you are giving in the insert file
<<< var user = mongoose.model('users',{ >>> in insert.js

This "users" name shouldn't be same when you declare a model that should be different 
in a same project.

Ответ 18

Чтобы решить эту проверку, если модель существует прежде, чем сделать создание:

if (!mongoose.models[entityDBName]) {
  return mongoose.model(entityDBName, entitySchema);
}
else {
  return mongoose.models[entityDBName];
}

Ответ 19

Если вы работаете с expressjs, вам может потребоваться переместить определение модели за пределы app.get(), поэтому он будет вызываться только один раз, когда создается script.