【问题标题】:Memory issues on knex.js when using streams使用流时 knex.js 上的内存问题
【发布时间】:2015-05-27 23:33:09
【问题描述】:

我正在尝试使用 knex.js 将整个 sqlite3 数据库表导出到 CSV。由于表最多可以有 300000 行,因此我使用流来避免内存问题。但是,如果我查看我的应用程序的内存使用情况,它高达 800MB,或者我有一个“内存不足”错误。

如何在 sqlite3 数据库上使用 knex.js 处理大型查询结果?

下面是代码示例:

knex.select().from(table).stream(function (stream) {
    var stringifier = stringify(opts);
    var fileStream = fs.createWriteStream(file);

    var i = 0;
    stringifier.on('readable', function() {
      var row;
      while (row = stringifier.read()) {
        fileStream.write(row);
        console.log("row " + i++); //debug
      }
    });

    fileStream.once('open', function(fd) {
      stream.pipe(stringifier);
    });
});

编辑

似乎 sqlite3 数据库的 knex.js 流是“假”流。 下面是 knex 中 sqlite3 的流函数源代码:

Runner_SQLite3.prototype._stream = Promise.method(function(sql, stream, options) {
    /*jshint unused: false*/
    var runner = this;
    return new Promise(function(resolver, rejecter) {
        stream.on('error', rejecter);
        stream.on('end', resolver);
        return runner.query(sql).map(function(row) {
            stream.write(row);
        }).catch(function(err) {
            stream.emit('error', err);
        }).then(function() {
            stream.end();
        });
    });
});

我们看到它在创建流之前等待请求执行 来自结果数组。

版本:

  • Knex.Js 0.7.5
  • 节点 0.12

感谢您的帮助。

【问题讨论】:

    标签: node.js sqlite stream out-of-memory knex.js


    【解决方案1】:

    我认为没有解决方案。我使用限制和偏移量通过 knex.js 逐步获取所有数据,并将每一行写入写入流中。 想要的人的实现示例:

     exportTable: function(table, writeStream) {
        var totalRows;
        var rowLimit = _config.ROW_LIMIT;
    
        return DatabaseManager.countAll(table).then(function(count) {
    
            totalRows = count[0]['count(*)'];
            var iterations = new Array(Math.ceil(totalRows / rowLimit));
    
            return Promise.reduce(iterations, function(total, item, index) {
    
                return _knex.select().from(table).limit(rowLimit).offset(index * rowLimit).map(function(row) {
                    writeStream.write(row);
                }).catch(function(err) {
                    return Promise.reject(err);
                });
    
            }, 0).then(function() {
                return Promise.resolve();
            }).catch(function(err) {
                return Promise.reject(err);
            });
    
        }).catch(function(err) {
            console.log(err);
            return Promise.reject(err);
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-20
      • 1970-01-01
      • 1970-01-01
      • 2020-12-09
      • 1970-01-01
      • 2012-02-22
      • 1970-01-01
      • 2018-10-14
      相关资源
      最近更新 更多