2017-07-20 12 views
0

こんにちは、私はデータベースから大量のデータを読み込むファイルに取り組んでいます。次に、nodejs内のjson2csvというモジュールを使用して、データセットを変換し、csvファイルに書き込みます。ここにjson2csvモジュールのリンクがあります。 https://www.npmjs.com/package/json2csv このモジュールを使用すると、データをcsvデータに変換しますが、問題は、データセットが大きくなりすぎてメモリに書き込まれずにクラッシュするためです。私はすべてのデータを書き込むのではなく、データの小さな断片を書くことができる方法はありますか?ここまで私がこれまで持っていたことがあります。nodeJSを使用して大きなデータセットをCSVファイルに書き込む方法は?

/*require the ibm_db module*/ 
var ibmdb = require('ibm_db'); 
var fs = require("fs"); 
var json2csv = require('json2csv'); 
var db2query = "SELECT DISTINCT DISCEVNT.EVENT_RUNID, DISCEVNT.EVENT_TIME, DISCEVNT.EVENT_SEVERITY, DISCEVNT.EVENT_ATTRIBUTE, DISCEVNT.EVENT_DESC, DISCEVNT_ATTR_IP.DE_IP, DISCEVNT_ATTR_IP.DE_HOSTNAME, DISCEVNT_ATTR_IP.DE_FQDN, DISCRUN.SERVERID_X FROM (DB2INST2.DISCEVNT DISCEVNT INNER JOIN DB2INST2.DISCRUN DISCRUN ON (DISCEVNT.EVENT_RUNID = DISCRUN.DISCOVERRUNID_X)) INNER JOIN DB2INST2.DISCEVNT_ATTR_IP DISCEVNT_ATTR_IP ON (DISCEVNT_ATTR_IP.DE_ATTR = DISCEVNT.EVENT_ATTRIBUTE) WHERE (DISCEVNT.EVENT_RUNID BETWEEN 2017071400000000 AND 2017071900000000) ORDER BY DISCEVNT.EVENT_TIME ASC;"; 
var db2setup = "DRIVER={DB2};DATABASE=CMDB;UID=user;PWD=password!;HOSTNAME=localhost;port=3000"; 
var dataJson = []; 
var fields = ['EVENT_RUNID','EVENT_TIME','EVENT_SEVERITY','EVENT_ATTRIBUTE','EVENT_DESC','DE_IP','DE_HOSTNAME','DE_FQDN','SERVERID_X']; 
console.log("Test program to access DB2 sample database"); 

/*Connect to the database server 
    param 1: The DSN string which has the details of database name to connect to, user id, password, hostname, portnumber 
    param 2: The Callback function to execute when connection attempt to the specified database is completed 
*/ 
function getData(values){ 
    dataJson = values; 
    console.log(dataJson); 
    var csv = json2csv({ data: dataJson, fields: fields }); 
    console.log("CSV data:"); 
    console.log(csv[0]); 
    console.log(csv.length); 
    console.log(dataJson.length); 
    console.log(dataJson[0]); 
    fs.writeFile('C:\\Users\\ztaddmusr\\Desktop\\CSV FILES\\file.csv', csv, function(err) { 
     if (err) throw err; 
     console.log('file saved'); 
    }); 

    } 

ibmdb.open(db2setup, function(err, conn) 
{ 
     if(err) { 
     /* 
      On error in connection, log the error message on console 
     */ 
      console.error("error: ", err.message); 
     } else { 

     /* 
      On successful connection issue the SQL query by calling the query() function on Database 
      param 1: The SQL query to be issued 
      param 2: The callback function to execute when the database server responds 
     */ 
     conn.query(db2query, function(err, data) { 

     if(err) { 
     /* 
      On error in connection, log the error message on console 
     */ 
      console.error("error: ", err.message); 
     } else { 
      //console.log(data); 

      getData(data); 
      console.log('Data finished retrieving from the datatbase. Now will write to file.') 

     } 
      /* 
       Close the connection to the database 
       param 1: The callback function to execute on completion of close function. 
      */ 
      conn.close(function(){ 
       console.log("Connection Closed"); 
      }); 
     }); 
    } 
}); 
//var csv = json2csv({ data: dataJson, fields: fields }); 
//console.log(csv); 
//fs.writeFile('file.csv', csv, function(err) { 
// if (err) throw err; 
// console.log('file saved'); 
//}); 

私はループを使用しようとしていましたが、つまずいていました。助けをよろしくお願いします。

+0

エラーは何ですか?無効な文字列の長さ、私は、これはので、私はそれが動作以下の行をseectときbecasueメモリである知っている: – Trufa

+0

はnodejsここ – David

+0

@Trufaストリーム(!strの==「」){ ^ 例外RangeError場合はエラーで使用するようにしてください。 –

答えて

0

co(npmパッケージ)などの実装でES6を使用する場合は、ジェネレータを使用できます。次に、パーティションに応じて非同期コードの実行を停止し、チャンクを使用してファイルに追加することができます。

このような何かが(それをコンパイルしていない。エラーがあるかもしれません):

function* writeToCsv(csvObj){ 
    let chunkedArr = chunkify(csvObj); 
    chunkedArr.forEach(co.wrap(chunk => { 
    co.wrap(writeChunkToCsv(chunk))(dir) 
    })) 
} 

function* writeChunkToCsv(chunk){ 
    return dir => { 
    yield fs.writeFile(dir, csv); 
    } 
} 

function chunkify(arr, partitions){ 
    let ansArr = []; 
    for(let i = 0, currentArr = []; i < arr.length; i++){ 
    if(i%(arr.length/partitions) === 0 || i === arr.length){ 
     ansArr = ansArr.push([...currentArr]); 
     currentArr = []; 
    } 
    else{ 
     currentArr.push(arr[i]); 
    } 
    } 
    return ansArr; 
} 
+0

async awaitを使用して、非同期に同期を実行する実装を行うこともできます(特にESバージョンが6未満の場合)。発電機はそれを行うための一つの方法です。 –

関連する問題