Mongoose脚本执行drop()挂起,数据插入也失败求助
问题分析与解决方案
核心问题原因
脚本无限挂起的根本原因是:当执行到connection.once('connected', ...)时,数据库连接已经处于就绪状态(readyState=1),这个connected事件不会再触发,导致事件回调里的删除集合、插入数据等逻辑永远无法执行,脚本因此卡在原地。
修复方案
直接移除connection.once('connected', ...)的包裹逻辑——既然已经通过console.log(connection.readyState)确认连接就绪,无需再等待该事件。如果要兼容连接尚未完全建立的场景,可改用await connection.asPromise()确保连接完成。
修改后的完整脚本
const axios = require("axios"); const XLSX = require("xlsx"); const fs = require("fs"); const path = require("path"); const mongoose = require("mongoose"); const connection = require("../../../config/connection"); const MdProdCat = require("../../../models/MdProdCat"); (async () => { try { // Download the .xlsx file console.log("=== Commencing MD Product Category import..."); console.log("Downloading .xlsx file..."); const response = await axios.get( "https://assets.mydeal.com.au/content/marketplace/MyDeal_Product_Category_List.xlsx", { responseType: "arraybuffer" } ); console.log("Saving .xlsx file..."); // Save the file to the project directory console.log("Saving .xlsx file..."); const xlsxFilePath = path.join( __dirname, "MyDeal_Product_Category_List.xlsx" ); fs.writeFileSync(xlsxFilePath, Buffer.from(response.data)); console.log("Saved .xlsx file"); // Convert the .xlsx file to .csv format console.log("Converting .xlsx to .csv..."); const workbook = XLSX.read(response.data, { type: "buffer" }); const sheetNameList = workbook.SheetNames; const csvData = XLSX.utils.sheet_to_csv(workbook.Sheets[sheetNameList[0]]); console.log("Converted .xlsx to .csv"); // Convert the CSV data to an array of JSON objects console.log("Converting .csv to JSON..."); const rows = csvData.split("\n").slice(1); // skip the header row const json = rows .filter((line) => line.trim()) // skip empty rows .map((line) => { const [CategoryID, Breadcrumbs] = line.split(","); return { _id: parseInt(CategoryID), Breadcrumbs }; }); console.log("Converted .csv to JSON"); // Check the connection to the database console.log("Connection state: ", connection.readyState); // 确保连接完全就绪(兼容连接尚未建立的场景) await connection.asPromise(); // Drop the collection in case it already exists try { // Drop the collection console.log("Dropping collection if it already exists"); await connection.dropCollection('mdprodcats'); console.log("Collection dropped successfully"); } catch (error) { if (error.message === 'ns not found') { // Ignore the error if the collection does not exist console.log('Collection does not exist. Continuing...'); } else { // Throw any other errors throw error; } } // Insert the JSON data into the MongoDB collection console.log("Inserting data..."); await MdProdCat.insertMany(json); console.log("Data inserted successfully"); // Close the connection console.log("Closing connection..."); await connection.close(); console.log("Connection closed"); console.log("=== Import completed successfully"); process.exit(); } catch (error) { console.error("An error occurred:", error); process.exit(1); } })();
额外说明
connection.asPromise()是Mongoose提供的方法,会等待连接成功建立或抛出连接失败错误,比监听connected事件更适配异步流程。- 移除
connection.once('connected', ...)后,所有数据库操作会直接在已连接的上下文执行,不会再出现挂起问题。
内容的提问来源于stack exchange,提问作者K the Bae
相关产品推荐
相关产品推荐

