使用stream时,knex.js上的内存问题

我想用knex.js将整个sqlite3数据库表导出为CSV。 由于表可以达到300000行,我使用stream没有内存问题。 但是,如果我看我的应用程序的内存使用高达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.jsstream是“假”stream。 下面是knex中sqlite3的stream函数的源代码:

 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(); }); }); }); 

我们看到它在从结果数组创buildstream之前等待请求被执行。

版:

  • Knex.Js 0.7.5
  • 节点0.12

Thx为您提供帮助。

我认为没有解决办法。 我使用限制和偏移量来获取与knex.js一步一步的所有数据,我写在写入stream的每一行。 对于那些想要的实现示例:

  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); }); }