Подтвердить что ты не робот

Большой CSV для JSON/Object в Node.js

Я пытаюсь сделать что-то похожее на то, что это должно быть не только достаточно простым, но достаточно общей задачей, чтобы для этого были доступны простые пакеты. Я хочу взять большой CSV файл (экспорт из таблицы реляционных баз данных) и преобразовать его в массив объектов JavaScript. Кроме того, я хотел бы экспортировать его в файл .json.

Пример CSV:

a,b,c,d
1,2,3,4
5,6,7,8
...

Желаемый JSON:

[
{"a": 1,"b": 2,"c": 3,"d": 4},
{"a": 5,"b": 6,"c": 7,"d": 8},
...
]

Я пробовал несколько парсеров node CSV, стримеров, самопровозглашенных библиотек CSV-to-JSON, но я не могу получить результат, который я хочу, или если я могу его использовать, только если файлы меньше. Размер моего файла составляет около 1 ГБ с ~ 40 м строк (что создало бы 40 м объектов). Я ожидаю, что для предотвращения проблем с памятью потребуется потоковая передача ввода и/или вывода.

Вот пакеты, которые я пробовал:

Я использую node 0.10.6 и хочу получить рекомендацию о том, как легко выполнить это. Возможно, мой собственный вариант может быть лучшим, но я не уверен, с чего начать все функции потоковой передачи node, тем более, что они изменили API в 0.10.x.

4b9b3361

Ответ 1

Хотя это далеко не полный ответ, вы можете найти свое решение на https://github.com/dominictarr/event-stream. Адаптированный пример из файла readme:

    var es = require('event-stream')
    es.pipeline(                         //connect streams together with `pipe`
      process.openStdin(),              //open stdin
      es.split(),                       //split stream to break on newlines
      es.map(function (data, callback) { //turn this async function into a stream
        callback(null
          , JSON.stringify(parseCSVLine(data)))  // deal with one line of CSV data
      }), 
      process.stdout
      )

После этого я ожидаю, что на каждой строке у вас будет множество строковых объектов JSON. Затем это необходимо преобразовать в массив, с которым вы можете сделать и добавить , в конец каждой строки, удалив его последним, а затем добавив [ и ] в начало и конец файл.

Функция

parseCSVLine должна быть настроена так, чтобы присваивать значения CSV правильным свойствам объекта. Это можно сделать довольно легко после прохождения первой строки файла.

Я замечаю, что библиотека не тестировалась на 0.10 (по крайней мере, не с Travis), так что будьте осторожны. Возможно, запустите npm test в источнике.

Ответ 2

Проверьте модуль node.js csvtojson, который можно использовать в качестве библиотеки, инструментов командной строки или плагина веб-сервера. https://www.npmjs.org/package/csvtojson. исходный код можно найти по адресу: https://github.com/Keyang/node-csvtojson

или установить из репозитория NPM:

npm install -g csvtojson

Он поддерживает любой размер csv данных/тип поля/вложенный json и т.д. Множество функций.

Пример

var Converter=require("csvtojson").core.Converter;

var csvConverter=new Converter({constructResult:false, toArrayString:true}); // The constructResult parameter=false will turn off final result construction in memory for stream feature. toArrayString will stream out a normal JSON array object.

var readStream=require("fs").createReadStream("inputData.csv"); 

var writeStream=require("fs").createWriteStream("outpuData.json");

readStream.pipe(csvConverter).pipe(writeStream);

Вы также можете использовать его как инструмент cli:

csvtojson myCSVFile.csv

Ответ 3

Я нашел что-то более легкое для чтения csv-данных с помощью csvtojson.

Здесь код:

var Converter = require("csvtojson").Converter;
var converter = new Converter({});
converter.fromFile("sample.csv",function(err,result){
  var csvData = JSON.stringify
  ([
    {resultdata : result[0]},
    {resultdata : result[1]},
    {resultdata : result[2]},
    {resultdata : result[3]},
    {resultdata : result[4]}
  ]);
  csvData = JSON.parse(csvData);
  console.log(csvData);
});

Ответ 4

Я рекомендую реализовать логику самостоятельно. Node.js на самом деле довольно хорош в таких задачах.

Следующее решение использует потоки, поскольку они не будут взорвать вашу память.

Установить зависимости

npm install through2 split2 --save

Код

import through2 from 'through2'
import split2 from 'split2'

fs.createReadStream('<yourFilePath>')
  // Read line by line
  .pipe(split2())
  // Parse CSV line
  .pipe(parseCSV()) 
  // Process your Records
  .pipe(processRecord()) 

const parseCSV = () => {
  let templateKeys = []
  let parseHeadline = true
  return through2.obj((data, enc, cb) => {
    if (parseHeadline) {
      templateKeys = data
        .toString()
        .split(';')
      parseHeadline = false
      return cb(null, null)
    }
    const entries = data
      .toString()
      .split(';')
    const obj = {}
    templateKeys.forEach((el, index) => {
      obj[el] = entries[index]
    })
    return cb(null, obj)
  })
}

const processRecord = () => {
  return through2.obj(function (data, enc, cb) {
    // Implement your own processing 
    // logic here e.g.:
    MyDB
      .insert(data)
      .then(() => cb())
      .catch(cb)
  })
}

Для получения дополнительной информации об этой теме посетите Stefan Baumgartners, отличный учебник на эту тему.