web-dev-qa-db-fra.com

Impossible d'écraser le modèle une fois compilé Mongoose

Pas sûr de ce que je fais mal, voici mon 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 })
    });

et voici mon 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); 
   });

Chaque fois que j'essaye de lancer check.js, j'obtiens cette erreur

Impossible d'écraser le modèle 'utilisateurs' une fois compilé .

Je comprends que cette erreur est due à l’incohérence de Schema, mais je ne vois pas où cela se produit? Je suis assez nouveau pour mangouste et nodeJS.

Voici ce que je reçois de l'interface client de ma 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 
  } 
>
63
Anathema.Imbued

L'erreur se produit car un schéma est déjà défini et vous le définissez à nouveau. En règle générale, vous devez instancier le schéma une fois, puis demander à un objet global de l'appeler lorsqu'il en a besoin. 

Par exemple:

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

Donc, une autre raison pour laquelle vous pourriez obtenir cette erreur est si vous utilisez le même modèle dans différents fichiers mais que votre chemin require a un cas différent. Par exemple, dans ma situation, j'avais:

require('./models/User') dans un fichier, puis dans un autre fichier où j'avais besoin d'accéder au modèle utilisateur que j'avais require('./models/user').

Je suppose que la recherche de modules et de mangoustes le traite comme un fichier différent. Une fois que je me suis assuré que le cas correspondait dans les deux cas, ce n'était plus un problème.

122
jonnie

J'ai eu ce problème lors des tests unitaires.

La première fois que vous appelez la fonction de création de modèle, Mongoose enregistre le modèle sous la clé que vous fournissez (par exemple, "utilisateurs"). Si vous appelez la fonction de création de modèle avec la même clé plusieurs fois, Mangouste ne vous laissera pas écraser le modèle existant.

Vous pouvez vérifier si le modèle existe déjà en mangouste avec:

let users = mongoose.model('users')

Cela provoquera une erreur si le modèle n'existe pas, vous pouvez donc l'envelopper dans un try/catch afin d'obtenir le modèle ou le créer:

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

J'avais ce problème alors que je "regardais" des tests ... Lorsque les tests ont été modifiés, la montre a répété les tests, mais ils ont échoué pour cette raison.

Je l'ai corrigé en vérifiant si le modèle existe, puis l'utiliser, sinon le créer.

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

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

J'ai rencontré ce problème et ce n'était pas à cause des définitions de schéma mais du mode hors connexion sans serveur - j'ai simplement réussi à le résoudre avec ceci:

serverless offline --skipCacheInvalidation

Ce qui est mentionné ici https://github.com/dherault/serverless-offline/issues/258

J'espère que cela aidera quelqu'un d'autre qui construit son projet en mode sans serveur et en mode hors connexion.

15
user5301210

Si vous le faites ici, il est possible que vous ayez le même problème que moi… .. Mon problème était que je définissais un autre modèle du même nom . J'ai appelé ma galerie et mon modèle de fichier "Fichier". Vous copiez et collez!

11
James Harrington

Cela m'est arrivé quand j'écris comme ceci:

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

Cependant, le vrai chemin est '../myUser/User.js'

6
ip192

Si vous utilisez Serverless hors ligne et ne souhaitez pas utiliser --skipCacheInvalidation, vous pouvez très bien utiliser:

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

Je sais qu’il existe une solution acceptée, mais j’estime que la solution actuelle génère beaucoup de problèmes, afin que vous puissiez tester les modèles. Ma solution consiste essentiellement à prendre votre modèle et à le placer dans une fonction entraînant le renvoi du nouveau modèle si le modèle n'a pas été enregistré, mais le modèle existant s'il le est.

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

Ouvrir et fermer des connexions partout est frustrant et ne se comprime pas bien.

De cette façon, si je demandais au modèle deux endroits différents ou plus précisément dans mes tests, je ne recevrais pas d'erreur et toutes les informations correctes seraient renvoyées.

3
Moosecouture

Pour résoudre ce problème, vérifiez si le modèle existe avant de procéder à la création:

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

La définition de schéma doit être unique pour une collection, mais pas plus d'un schéma pour une collection.

0
KARTHIKEYAN.A

Vous pouvez facilement résoudre cela en faisant 

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

c'est parce que votre schéma est déjà, validez avant de créer un nouveau schéma.

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

Ce problème peut se produire si vous définissez 2 schémas différents avec le même nom de collection.

0
Rohit Reddy Abbadi
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.
0
Rohit Jangid

J'ai résolu ceci en ajoutant

mongoose.models = {}

avant la ligne: 

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

J'espère que cela résoudra votre problème

0
Toufiq
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" } });
0
Rohit Jangid

J'ai une situation où je dois créer le modèle dynamiquement à chaque demande et à cause de cela, j'ai reçu cette erreur, cependant, ce que j'ai utilisé pour la corriger utilise la méthode deleteModel comme suit:

var contentType = 'Product'

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

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

mongoose.deleteModel(contentType);

J'espère que cela pourrait aider n'importe qui.

0
Engr.MTH