如何解决MongoNotConnectedError:执行操作前需连接客户端的问题
解决MongoNotConnectedError:数据库种子文件执行时的连接问题
我在开发项目时,使用种子文件为数据库填充测试数据,运行Node.js文件时出现如下错误:
Database connected D:\OUWork\Year 6\TM470\Project\node_modules\mongodb\lib\operations\execute_operation.js:24 throw new error_1.MongoNotConnectedError('Client must be connected before running operations'); ^ MongoNotConnectedError: Client must be connected before running operations at executeOperationAsync (D:\OUWork\Year 6\TM470\Project\node_modules\mongodb\lib\operations\execute_operation.js:24:19) at D:\OUWork\Year 6\TM470\Project\node_modules\mongodb\lib\operations\execute_operation.js:12:45 at maybeCallback (D:\OUWork\Year 6\TM470\Project\node_modules\mongodb\lib\utils.js:338:21) at executeOperation (D:\OUWork\Year 6\TM470\Project\node_modules\mongodb\lib\operations\execute_operation.js:12:38) at Collection.insertOne (D:\OUWork\Year 6\TM470\Project\node_modules\mongodb\lib\collection.js:148:57) at NativeCollection.<computed> [as insertOne] (D:\OUWork\Year 6\TM470\Project\node_modules\mongoose\lib\drivers\node-mongodb-native\collection.js:226:33) at Model.$__handleSave (D:\OUWork\Year 6\TM470\Project\node_modules\mongoose\lib\model.js:309:33) at Model.$__save (D:\OUWork\Year 6\TM470\Project\node_modules\mongoose\lib\model.js:388:8) at D:\OUWork\Year 6\TM470\Project\node_modules\kareem\index.js:387:18 at D:\OUWork\Year 6\TM470\Project\node_modules\kareem\index.js:113:15 { [Symbol(errorLabels)]: Set(0) {} }
种子文件的JavaScript代码如下:
const mongoose = require('mongoose'); const MusicProduct = require('../database_models/musicproduct'); const BookProduct = require('../database_models/bookproduct'); const musicAlbums = require('./musicseeds'); const bookNovels = require('./bookseeds'); // Connnect to MongoDB mongoose.connect('mongodb://127.0.0.1/music-bookApp'); mongoose.set('strictQuery', false); // Logic to check that the database is connected properly mongoose.connection.on('error', console.error.bind(console, 'connection error:')); mongoose.connection.once('open', () => { console.log('Database connected'); }); //Fill the Music products database with 20 random albums taken from the music seeds file const musicSeedDB = async () => { await MusicProduct.deleteMany({}); for (let i = 0; i < 20; i++) { const randomMusic20 = Math.floor(Math.random() * 20); //const musicStock = Math.floor(Math.random() * 10) + 1; const musicItem = new MusicProduct({ artistName: musicAlbums[randomMusic20].artist, albumName: musicAlbums[randomMusic20].title, //musicStock }) await musicItem.save(); } }; //Fill the Book products database with 20 random books taken from the music seeds file const bookSeedDB = async () => { await BookProduct.deleteMany({}); for (let i = 0; i < 20; i++) { const randomBook20 = Math.floor(Math.random() * 20); //const bookStock = Math.floor(Math.random() * 10) + 1; const bookItem = new BookProduct({ bookAuthor: bookNovels[randomBook20].authors, bookName: bookNovels[randomBook20].title, //ookStock }) await bookItem.save(); } }; // Close the connection to DB after finish seeding musicSeedDB().then(() => { mongoose.connection.close(); }); bookSeedDB().then(() => { mongoose.connection.close(); });
运行后数据库已成功更新为种子数据,但需要消除该错误,解决方法如下:
错误原因
- 连接时机不匹配:
mongoose.connect()是异步操作,直接调用种子函数时,数据库可能还未完成连接,导致部分操作执行时连接未就绪。 - 重复关闭连接:两个种子函数并行执行,其中一个完成后立即关闭连接,另一个函数此时仍在执行数据库操作,触发连接已关闭的错误。
修复后的代码
const mongoose = require('mongoose'); const MusicProduct = require('../database_models/musicproduct'); const BookProduct = require('../database_models/bookproduct'); const musicAlbums = require('./musicseeds'); const bookNovels = require('./bookseeds'); mongoose.set('strictQuery', false); // 封装完整种子流程,确保连接就绪后再执行操作 const seedDatabase = async () => { try { // 等待数据库连接成功 await mongoose.connect('mongodb://127.0.0.1/music-bookApp'); console.log('Database connected'); // 依次执行音乐和书籍的种子填充 await musicSeedDB(); await bookSeedDB(); console.log('Seeding completed successfully'); } catch (err) { console.error('Seeding failed:', err); } finally { // 所有操作完成后统一关闭连接 await mongoose.connection.close(); console.log('Database connection closed'); } }; const musicSeedDB = async () => { await MusicProduct.deleteMany({}); for (let i = 0; i < 20; i++) { const randomMusic20 = Math.floor(Math.random() * 20); const musicItem = new MusicProduct({ artistName: musicAlbums[randomMusic20].artist, albumName: musicAlbums[randomMusic20].title }); await musicItem.save(); } }; const bookSeedDB = async () => { await BookProduct.deleteMany({}); for (let i = 0; i < 20; i++) { const randomBook20 = Math.floor(Math.random() * 20); const bookItem = new BookProduct({ bookAuthor: bookNovels[randomBook20].authors, bookName: bookNovels[randomBook20].title }); await bookItem.save(); } }; // 启动种子流程 seedDatabase();
修复说明
- 使用
await mongoose.connect()确保数据库连接完成后再执行后续操作,彻底避免连接未就绪的问题。 - 将两个种子函数放在同一异步流程中依次执行,避免并行操作导致的资源冲突。
- 用
try/catch/finally统一处理错误和连接关闭,确保所有种子操作完成后才关闭数据库连接。 - 移除原有的
mongoose.connection.once('open')监听,因为await mongoose.connect()已经会等待连接成功。
内容的提问来源于stack exchange,提问作者NewtoJavaHelp
相关产品推荐
相关产品推荐

