You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mongoose从CSV导入数据到MongoDB Atlas仅插部分数据报错如何解决

问题原因
  • 响应重复发送:你在for循环的单条保存回调里调用res.render,第一条数据保存成功后就已经向客户端返回了响应,后续保存成功再调用该方法就会触发ERR_HTTP_HEADERS_SENT报错,同时打断未完成的保存操作,导致数据插入不全。
  • 文件上传逻辑缺失:express原生不解析multipart/form-data格式的文件上传请求,直接从req.body.file拿不到上传的CSV文件路径,需要配合文件上传中间件处理。
  • 异步逻辑混乱:async/await和then混用,且单条循环保存数据库的操作没有做异步等待,逻辑执行顺序不可控。
修复方案

首先安装文件上传依赖multer:

npm install multer

修改后的完整代码如下:

const csvtojson = require("csvtojson");
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const mongoose = require("mongoose");
const multer = require('multer');
const Student = require("./models/student");
const encrypt = require("mongoose-encryption")

const app = express();

// 配置multer临时存储上传的文件
const upload = multer({ dest: 'uploads/' })

app.use(express.static("public"));
app.set("views", "./views");
app.set("view engine", "ejs");
app.use(
  bodyParser.urlencoded({
    extended: true,
  })
);

try {
  mongoose.connect(
    process.env.URL,
    { useNewUrlParser: true, useUnifiedTopology: true },
    () => console.log("Mongoose connected")
  );
} catch (e) {
  console.log("Failed to connect to mongoose!");
}

app.get("/test", function (req, res) {
  res.render("test");
});

// 用multer中间件接收name为file的上传文件
app.post("/test", upload.single('file'), async function (req, res) {
  try {
    // 拿到上传后的临时文件路径
    const csvfilepath = req.file.path;
    // 转换csv为json
    const jsonArr = await csvtojson().fromFile(csvfilepath);
    // 批量插入数据,比循环单条插入效率高很多
    await Student.insertMany(jsonArr.map(item => ({
      fname: item.fname,
      // 注意这里如果csv里姓的列名是lname就改成item.lname,别写错字段
      lname: item.nlame,
      prn: item.prn,
      username: item.email,
      password: item.password,
      department: item.department,
      year: item.year,
      batch: item.batch,
      placement_Status: item.placement_Status
    })));
    // 所有数据插入完成后再返回响应
    res.render("test");
  } catch (err) {
    console.log("操作失败:", err);
    res.status(500).send("数据导入失败");
  }
});

app.listen(3000, function () {
    console.log("Server started on port 3000...");
  });
额外注意事项
  • 前端提交CSV的表单需要添加enctype="multipart/form-data"属性,示例表单代码:
<form action="/test" method="post" enctype="multipart/form-data">
  <input type="file" name="file" accept=".csv">
  <button type="submit">上传</button>
</form>
  • 请确认CSV文件的列名和代码中映射的字段名完全一致,避免出现字段为空的情况。
  • 如果需要对导入失败的数据做单独处理,可以在insertMany的参数中添加{ordered: false}配置,这样单条数据插入失败不会打断整体导入流程,后续可以拿到错误列表单独处理。

内容的提问来源于stack exchange,提问作者Tejas Sawant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 03:00:00