简体   繁体   English

将 MySQL 查询流式传输到 NodeJS 中的 CSV 文件

[英]Stream MySQL query to CSV file in NodeJS

How can I efficiently write a mysql result set to a file in CSV format without loading all of the rows into memory?如何在不将所有行加载到内存中的情况下有效地将 mysql 结果集写入 CSV 格式的文件? NodeJS code, please. NodeJS 代码,请。

This example works with npm packages csv-stringify and either mysql or mysql2 and any Node version that supports the async keyword.此示例适用于 npm 包 csv-stringify 和 mysql 或 mysql2 以及任何支持 async 关键字的 Node 版本。

const csvstringify = require('csv-stringify');
const fs = require('fs');

const outputStream = fs.createWriteStream('output.csv', {encoding: 'utf8'});

// Capture events on the outputStream before writing begins
const finishedWriting = new Promise((resolve, reject)=>
  outputStream.on('finished', resolve).on('error', reject));

const connection = __Create a mysql2 Connection object here__
const generator = connection.connection.query('SELECT...');
let recordsProcessed = 0;

try {
  await new Promise((resolve, reject) => {
    // When using a connection pool, the 'error' connection event is called only
    // when enableKeepAlive is true. See:
    // https://github.com/sidorares/node-mysql2/issues/677#issuecomment-588530194
    // Without this handler, this code will hang if the database connection is
    // lost while reading the result set.
    connection.on('error', reject);

    generator
      .on('result', row => ++recordsProcessed) // Counting rows as an example
      .stream({highWaterMark: 10})
      .on('error', reject)
      .on('end', resolve)
      .pipe(csvstringify({header: true}))
      .pipe(outputStream)
      .on('error', error => {
        // Handle stream write error
        // See also https://github.com/sidorares/node-mysql2/issues/664
        // Data is being sent from server to client; without calling destroy, the
        // connection will go back to the pool and will be unusable. The
        // callback provided to destroy() is never called.
        connection.destroy(); // This appears to cause file descriptor leaks
        reject(error);
      });
  });
}
finally {
  connection.on('error', error => console.log(error)); // Remove the handler.
                                                       // Is there a better way?
}

await finishedWriting;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM