2014-04-02 39 views
0

有沒有一種很好的方式將大型CSV(4GB +)以流的形式放入NodeJS中的postgres數據庫中?Nodejs流CSV,在postgres中創建表並使用COPY導入從

特別是,我想採取第一行(標題行),並製作一個創建查詢。然後,我想將文件的其餘部分從聲明中複製到副本。

這將是可行的,如果我只是想發送到複製命令,例如:

function copyStreamIntoTable (inputStream) { 
    var deferred = Q.defer(); 
    pg.connect("pg://[email protected]/npi_demo", function (err, client) { 
    var s = client.copyFrom("COPY hptc (code, type, classification, specialization, definition, notes) FROM STDIN WITH CSV HEADER"); 

    inputStream.pipe(through(function (data) { 
     this.queue(data.toString("ascii")); 
    })).pipe(s).on('close', function() { 
     deferred.resolve(); 
    }); 
    }); 

    return deferred.promise; 
} 

但我想流有第一線讀取,然後運行創建查詢。一旦創建查詢完成,id就像將流的其餘部分流到copyFrom。

有沒有一個優雅的方式來做到這一點?我仍然是nodejs和流的新手。

+0

檢查node.js的PostgreSQL接口是否明確支持其API中的「COPY」。如果可能,您將希望使用任何此類支持,而不是直接嘗試使用「COPY」語句。 –

+0

@CraigRinger謝謝 - 我會檢查一下。 –

+0

作爲一個方面說明,我被節點中的流超級困惑......我知道我可以使用類似於readline的東西讀取第一行......並且我可以使用readline將其餘部分寫入postgres流.. 。但爲了正確地尊重pg應用的背壓,事情似乎變得複雜得多,除非我使用管道 –

回答

0

想出了一個更普遍的回答我的問題:

var fs = require('fs'), 
    through = require('through'), 
    split = require('split'); 

var inFile = fs.createReadStream('./lines'), 
    outFile = fs.createWriteStream('./out'), 
    headers; 

var th = through(function (data) { 
    if (typeof headers === "undefined") { 
    headers = data; 
    th.pause(); 
    setTimeout(function() { th.resume(); }, 5000); 
    } else { 
    this.queue(data + "\n"); 
    } 
}); 

inFile.pipe(split()) 
    .pipe(th) 
    .pipe(outFile) 
    .on("close", function() { 
    console.log("had headers: " + headers); 
    }); 

,其中通過和分裂,是故宮安裝流幫手。

如果INFILE的內容是:

one 
two 
three 

輸出將had headers: one和不過outFile將有內容

two 
three 

在我的具體問題的背景下 - 超時會可以通過查詢db來創建表來替換,寫入out文件將被替換爲寫入copyFrom流。

+0

很酷,謝謝。你知道有沒有關於CSV大小的建議?你把你的文件分成幾個csv字符串還是隻有一個?任何recos? –

+0

沒有什麼具體的分裂 - 我用這種方法導入了一個4.5GB的csv –

相關問題