Je prépare un script de création de base de données dans Node.js et Mongoose . Comment puis-je vérifier si la base de données existe déjà et, le cas échéant, supprimez-la à l'aide de Mongoose?
Je ne pouvais pas trouver un moyen de le laisser tomber avec Mongoose.
Il n'y a pas de méthode pour supprimer une collection de mangouste, le mieux que vous puissiez faire est d'en supprimer le contenu:
Model.remove({}, function(err) {
console.log('collection removed')
});
Mais il existe un moyen d’accéder au pilote javascript natif de mongodb, qui peut être utilisé pour cela.
mongoose.connection.collections['collectionName'].drop( function(err) {
console.log('collection dropped');
});
Faites une sauvegarde avant d'essayer ceci au cas où quelque chose se passe mal!
Mongoose créera une base de données s'il n'y en a pas déjà une sur la connexion. Ainsi, une fois la connexion établie, vous pouvez simplement l'interroger pour voir s'il contient quelque chose.
Vous pouvez supprimer n'importe quelle base de données à laquelle vous êtes connecté:
var mongoose = require('mongoose');
/* Connect to the DB */
mongoose.connect('mongodb://localhost/mydatabase',function(){
/* Drop the DB */
mongoose.connection.db.dropDatabase();
});
Si vous modifiez la solution de @ hellslam comme ceci, alors cela fonctionnera
J'utilise cette technique pour supprimer la base de données après mes tests d'intégration
//CoffeeScript
mongoose = require "mongoose"
conn = mongoose.connect("mongodb://localhost/mydb")
conn.connection.db.dropDatabase()
//JavaScript
var conn, mongoose;
mongoose = require("mongoose");
conn = mongoose.connect("mongodb://localhost/mydb");
conn.connection.db.dropDatabase();
HTH au moins ça l’a fait pour moi, alors j’ai décidé de partager =)
Essayé réponses de @ hellslam et @ silverfighter. J'ai trouvé une condition de concurrence retardant mes tests. Dans mon cas, je lance des tests mocha et dans la fonction avant du test, je veux effacer toute la base de données. Voici ce qui fonctionne pour moi.
var con = mongoose.connect('mongodb://localhost/mydatabase');
mongoose.connection.on('open', function(){
con.connection.db.dropDatabase(function(err, result){
done();
});
});
Vous pouvez en lire plus https://github.com/Automattic/mongoose/issues/1469
Le problème que j'ai eu avec les autres solutions est qu'elles reposent sur le redémarrage de votre application si vous voulez que les index fonctionnent à nouveau.
Pour mes besoins (c'est-à-dire pouvoir exécuter un test unitaire sur toutes les collections d'archives nucléaires, puis les recréer avec leurs index), j'ai fini par implémenter cette solution:
Ceci repose sur les bibliothèques underscore.js et async.js pour assembler les index en parallèle, cela pourrait être résolu si vous êtes contre cette bibliothèque mais je laisse cela comme un exerciseur pour le développeur .
mongoose.connection.db.executeDbCommand( {dropDatabase:1}, function(err, result) {
var mongoPath = mongoose.connections[0].Host + ':' + mongoose.connections[0].port + '/' + mongoose.connections[0].name
//Kill the current connection, then re-establish it
mongoose.connection.close()
mongoose.connect('mongodb://' + mongoPath, function(err){
var asyncFunctions = []
//Loop through all the known schemas, and execute an ensureIndex to make sure we're clean
_.each(mongoose.connections[0].base.modelSchemas, function(schema, key) {
asyncFunctions.Push(function(cb){
mongoose.model(key, schema).ensureIndexes(function(){
return cb()
})
})
})
async.parallel(asyncFunctions, function(err) {
console.log('Done dumping all collections and recreating indexes')
})
})
})
Pour vider une collection particulière dans une base de données:
model.remove(function(err, p){
if(err){
throw err;
} else{
console.log('No Of Documents deleted:' + p);
}
});
Remarque:
Cela fonctionne pour moi à partir de Mongoose v4.7.0
:
mongoose.connection.dropDatabase();
La meilleure façon de supprimer votre base de données dans Mongoose dépend de la version de Mongoose que vous utilisez. Si vous utilisez une version de Mongoose version 4.6.4 ou ultérieure, cette méthode ajoutée dans cette version fonctionnera probablement très bien pour vous:
mongoose.connection.dropDatabase();
Dans les versions précédentes, cette méthode n'existait pas. Au lieu de cela, vous deviez utiliser un appel direct MongoDB:
mongoose.connection.db.dropDatabase();
Toutefois, si cette opération était exécutée juste après la création de la connexion à la base de données, elle pourrait éventuellement échouer en mode silencieux. Cela est lié au fait que la connexion est réellement asynchrone et n’a pas encore été configurée lorsque la commande est exécutée. Ce n'est normalement pas un problème pour les autres appels Mongoose comme .find()
, qui attendent jusqu'à ce que la connexion soit ouverte et ensuite exécutée.
Si vous examinez le code source du raccourci dropDatabase()
qui a été ajouté, vous constaterez qu'il a été conçu pour résoudre ce problème. Il vérifie si la connexion est ouverte et prête. Si tel est le cas, la commande est immédiatement déclenchée. Sinon, il enregistre la commande à exécuter lorsque la connexion à la base de données est ouverte.
Certaines des suggestions ci-dessus recommandent always de placer votre commande dropDatabase
dans le gestionnaire open
. Mais cela ne fonctionne que dans le cas où la connexion n'est pas encore ouverte.
Connection.prototype.dropDatabase = function(callback) {
var Promise = PromiseProvider.get();
var _this = this;
var promise = new Promise.ES6(function(resolve, reject) {
if (_this.readyState !== STATES.connected) {
_this.on('open', function() {
_this.db.dropDatabase(function(error) {
if (error) {
reject(error);
} else {
resolve();
}
});
});
} else {
_this.db.dropDatabase(function(error) {
if (error) {
reject(error);
} else {
resolve();
}
});
}
});
if (callback) {
promise.then(function() { callback(); }, callback);
}
return promise;
};
Voici une version simple de la logique ci-dessus qui peut être utilisée avec les versions antérieures de Mongoose:
// This shim is backported from Mongoose 4.6.4 to reliably drop a database
// http://stackoverflow.com/a/42860208/254318
// The first arg should be "mongoose.connection"
function dropDatabase (connection, callback) {
// readyState 1 === 'connected'
if (connection.readyState !== 1) {
connection.on('open', function() {
connection.db.dropDatabase(callback);
});
} else {
connection.db.dropDatabase(callback);
}
}
Une réponse mise à jour, pour 4.6.0+, si vous avez une préférence pour les promesses ( voir docs ):
mongoose.connect('mongodb://localhost/mydb', { useMongoClient: true })
.then((connection) => {
connection.db.dropDatabase();
// alternatively:
// mongoose.connection.db.dropDatabase();
});
J'ai testé ce code dans mon propre code, en utilisant mangouste 4.13.6. Notez également l’utilisation de l’option useMongoClient
( voir docs ). Les documents indiquent:
La logique de connexion par défaut de Mongoose est obsolète à partir de 4.11.0. Activez la nouvelle logique de connexion à l'aide de l'option useMongoClient, mais assurez-vous de tester vos connexions avant de mettre à niveau une base de code existante!
Mongoose 4.6.0+:
mongoose.connect('mongodb://localhost/mydb')
mongoose.connection.once('connected', () => {
mongoose.connection.db.dropDatabase();
});
Passer un rappel pour se connecter ne fonctionnera plus:
TypeError: impossible de lire la propriété 'ordersTakeWriteConcern' of null
beforeEach((done) => {
mongoose.connection.dropCollection('products',(error ,result) => {
if (error) {
console.log('Products Collection is not dropped')
} else {
console.log(result)
}
done()
})
})