如何使用PostgreSQL从nodejs中导出nodejs中的csv文件

时间:2014-02-19 11:15:21

标签: node.js postgresql csv heroku

nodejs文件在Heroku上,我使用PostgreSQL作为数据库 我想从视图中导出csv文件:

//我的PostgreSQL查询

var copyTo = require('pg-copy-streams').to; 
var csv = require('csv');
var fs = require('fs');

var stream =  client.query(copyTo('COPY (SELECT * FROM v_metric) TO
STDOUT WITH CSV HEADER DELIMITER as \'|\''));

//在csv中导出

csv().from(stream.pipe(process.stdout,{ end: false)).to(fs.createWriteStream('sample.csv'))

我没有任何结果,sample.csv为空。

任何想法?

提前谢谢

2 个答案:

答案 0 :(得分:2)

您可以使用专为此制作的pg-copy-streams npm模块:

    let data = '', copyTo = require('pg-copy-streams').to;
    pool.connect(function(pgErr, client, done) {
      if(pgErr) {
        //handle error
        return;
      }
      var stream = client.query(copyTo(`COPY (${query}) TO STDOUT With CSV HEADER`));
      stream.on('data', chunk => {
        data += chunk;
      })
      stream.on('end', response => {
        console.log(data)
        done();
      });
      stream.on('error', err => {
        done();
      })
    })

希望这有帮助。

答案 1 :(得分:1)

SQL Server的STDOUT将与您的节点进程不同。您可以尝试streaming the query results

var query = client.query('SELECT * FROM v_metric');
query.on('row', function(row) {
    //handle the row here
});

然后在您的处理程序中,如果您的数据不复杂(即没有分隔符或双引号),您可以跳过使用csv并迭代列以将它们转换为您写入写入流的字符串。可能更容易将列名称放在数组中,您可以将其作为SQL传递(通过加入',')并在处理程序中迭代,但您也可以使用Object.keys(row)提取列名。

更新:基于您的评论的示例:

var columns = ['country_cd','product_name','product_lvel','month_year','metric_name','val'];
var ws = fs.createWriteStream('sample.csv');

var query = client.query('SELECT '+columns.join(', ')+' FROM users');
query.on('row', function(row) {
    var values = [];
    // process column values; if you need to do special formatting (i.e. dates) don't loop and instead handle each one specially
    columns.forEach(function(col) {
        values = row[col];
    });
    ws.write(values.join('| '));
});

query.on('end', function(result) {
    ws.close();
});

如果您确实想使用csv,您可以创建一个您编写的流,以便将数据写入处理程序并将其提交到csv

另外注意,,是默认分隔符,因此如果您想使用其他内容,例如|,则需要在选项中指定。