NodeJS-根据stream从SQL Server导出

我在NodeJS的Web应用程序中工作,现在我想添加一个模块,用于根据stream/套接字将我的SQL Server数据库(10.000.000条logging)中的海量logging导出到.CSV文件。
如果有100个用户从服务器上下载数据(.csv),则会增加服务器 / 客户端的大量内存使用量。
我想,如果可能,将数据(.csv)保存到硬盘驱动器(客户端),否则保存到服务器/客户端内存(RAM)中。

Server.js

 var http = require('http'); var express = require('express'); var app = express(); var server = http.Server(app); var io = require('socket.io')(server); io.on('connection', function (socket) { console.log('Connection is ready!') socket.on('get_records', function (data) { var connection = new sql.Connection(config, function (err) { if (err) { console.log(err.message); } var request = new sql.Request(connection); request.stream = true; request.query("Select * from my_table"); // ... error checks request.on('recordset', function (recordset) { // Emitted once for each recordset in a query }); request.on('row', function (record) { // Emitted for each row in a recordset socket.emit('recieve_records', record); //send record by record to client }); request.on('error', function (err) { console.log(err.message); }); request.on('done', function (returnValue) { // Always emitted as the last one }); }); }); 

编辑 :见下面的post
StreamSaver.js – 下载时出错(networking失败)

如果使用socket.io传输文件,则没有简单/可靠的方法来启动下载对话框。 我find了3个解决scheme来保存文件:

  1. 这个答案 。 但是在保存之前,你必须把整个文件保存在RAM中。 +它有最大的BLOB大小限制。
  2. FileSaver模块。 同样的想法,包装成一个模块(在GitHub 5k星)。 仍然限于blob大小,并保持一切在记忆中。
  3. StreamSaver模块。 没有blob大小限制。 但在Firefox,IE,Edge中完全不起作用。

这就是为什么我build议你使用简单的HTTP进行文件传输。

然后,您可以简单地使用<a href="path/to/your/endpoint">标记下载它或从这里使用一些技巧。

所以如果你有Node.js可读stream发射对象,你可以使用'csv'模块并将其转换为'csv'。 然后只需将其pipe理到Express响应对象。

 var csv = require('csv'); router.get('/csv', function (req, res, next) { //Handle the connection here, you might decide to use connection pool is supported new sql.Connection(config, function (err) { if (err) { console.log(err.message); } //You can pipe mssql request as per docs var request = new sql.Request(connection); request.stream = true; request.query("Select * from my_table"); var stringifier = csv.stringify({header: true}); //Then simply call attachment and pipe it to the response res.attachment('sample.csv'); request.pipe(stringifier).pipe(res); }); });