Express 서버에서 CSV 업로드, 행 구문 분석 및 각 행을 MongoDB(Mongoose 사용)에 저장
다음 라이브러리가 필요합니다.
CSV 파일을 업로드하기 위한 양식 만들기 - multipart/form-data
파일 업로드는
multipart/form-data
을 통해 이루어져야 합니다. 이것은 저도 최근에 알게 된 내용이며 아마도 다른 게시물의 대상이 될 것입니다. 지금은 건너뛰겠습니다.멀터
multer
은 파일을 가져와 req.file
에 배치합니다. req.body
에서 파일을 찾을 것이라고 기대하지 마십시오. 이 파일에는 텍스트인 양식 필드 데이터만 포함됩니다. multer에 대한 자습서의 90%는 수신 파일을 디렉토리에 저장하는 방법을 설명합니다. 이것은 쓰기 권한이 없는 서버에 상주하므로 파일이 메모리에 상주하기를 원합니다.const multer = require("multer");
const parseCsv = multer().single("whatever-name-you-gave-to-the-input-field-in-your-form");
module.exports = {parseCsv}
이것은
req.file
에 파일을 배치할 미들웨어입니다.빠른 csv 및 streamifier
req.file
에는 buffer
속성이 있지만 노드의 createReadStream
에서는 읽을 수 없습니다. fs.createReadStream(buffer)
을 시도하면 이것이 파일이 아니라는 오류가 발생할 가능성이 높습니다. Node의 createReadStream
은 Buffer
의 인스턴스를 허용하지만(우리의 buffer
은 인스턴스임) 해당 인스턴스는 createReadStream
에서 읽을 수 없습니다. 이 SO answer에서 그것에 대해 배웠습니다. 내가 찾은 해결책은? streamifier
, 처음 알게 된 here . 소스 코드를 보면 req.file
의 버퍼를 createReadStream
으로 전달되는 읽을 수 있는 버퍼로 변환하는 마법을 부립니다. 이 도서관을 발견하게 되어 기뻤습니다.그래서 이렇게 스트림을 만듭니다.
const { buffer } = req.file;
streamifier.createReadStream(buffer)
@빠른 csv/구문 분석
@fast-csv/parse
은 csv에서 데이터가 포함된 스트림을 가져오고 몇 가지 이벤트를 호출하여 파일 내용을 구문 분석합니다. 모든 행에 대해 .on('data', data => callback)
을 호출하므로 원하는 대로 무엇이든 할 수 있습니다. 모든 행이 구문 분석되면 .on('end', rowCount => callback)
을 호출합니다. 이벤트 .on('error', callback)
이 validation capabilities과 관련이 있다고 생각하지만 아직 시도하지 않았습니다.fast-csv를
csv
으로 가져온 다음 .pipe(csv.parse())
을 호출할 수 있습니다(아래 예 참조). 또한 옵션을 csv.parse()
에 전달할 수 있습니다. 지금까지 사용한 옵션은 headers: true
(csv 파일에서 헤더 줄 건너뛰기, 문서 here 참조) 및 ignoreEmpty: true
(빈 줄 무시, 문서 here 참조)입니다.내 첫 번째 반복은 모든 행 구문 분석에서 문서 생성을 배치하는 것이 었습니다. DB에 데이터를 저장하는 비동기 특성과 CSV 파싱의 동기화 특성으로 인한 실수입니다. 첫 번째 문서가 저장되기 전에
'end'
이벤트가 트리거되어 내 전략과 서버 응답이 망가지는 것을 발견했습니다.나는 약간의 연구를했고 잘 작동하는 strategy을 찾았습니다. 구문 분석 된 행 (객체로 다시 반환됨)을 메모리의 배열에 추가하고
Model.create([ARRAY_OF_OBJECTS])
이벤트에서 Mongoose의 'end'
을 호출합니다. 이를 비동기화하고 클라이언트에 대한 서버 응답을 결정해야 합니다. 마찬가지로 저에게는 잘 작동하는 것 같습니다.const csv = require("@fast-csv/parse");
const streamifier = require("streamifier");
// somewhere below
router.post("/endpoint", [multerMiddlewareExplainedAbove], (req, res) => {
const { buffer } = req.file;
const dataFromRows = [];
streamifier
.createReadStream(buffer)
.pipe(csv.parse({ headers: true, ignoreEmpty: true })) // <== this is @fast-csv/parse!!
.on("data", (row) => {
dataFromRows .push(row);
})
.on("end", async (rowCount) => {
try {
const data = await MyModelName.create(dataFromRows );
res.status(200).json({ rowCount, data });
} catch (error) {
res.status(400).json({ error});
}
});
});
그것이 의미가 있기를 바랍니다. 나는 물건을 발견하는대로 물건을 추가 할 것입니다. 읽어 주셔서 감사합니다 (:
Reference
이 문제에 관하여(Express 서버에서 CSV 업로드, 행 구문 분석 및 각 행을 MongoDB(Mongoose 사용)에 저장), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/petrussola/upload-csv-parse-rows-and-save-each-row-to-mongodb-in-an-express-server-5738텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)