NodeJS-根据Stream从SQL Server导出

时间:2017-02-05 01:29:52

标签: sql-server node.js streaming

我在NodeJS中处理Web应用程序,现在我想添加一个模块,用于根据流/套接字将大量记录从我的SQL Server数据库(10.000.000记录)导出到.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
        });
    });
});

修改:见下文帖子 StreamSaver.js - Error in downloading (Network failed)

1 个答案:

答案 0 :(得分:1)

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

  1. answer。但是你必须在保存之前将整个文件保存在RAM中。 +它有最大blob大小限制。
  2. FileSaver模块。同样的想法,包装成一个模块(GitHub上的5k星)。仍限于blob大小,并将所有内容保存在内存中。
  3. StreamSaver模块。没有blob大小限制。但在Firefox,IE,Edge中根本不起作用。
  4. 这就是为什么我建议您使用简单的HTTP进行文件传输。

    然后您只需使用<a href="path/to/your/endpoint">标记即可下载或使用here中的一些技巧。

    因此,如果您有可发送对象的Node.js可读流,您可以使用'csv' module并将其转换为&#39; csv&#39;在飞行中。然后只需将其传递给Express响应对象。

    &#13;
    &#13;
    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);
    	});
    });
    &#13;
    &#13;
    &#13;

    还要检查csv-stringify文档,因为有一些有用的选项,例如headers:true(添加标题行)和其他选项。