В этом уроке вы узнаете, как использовать поток для более эффективной обработки больших наборов результатов.
Это руководство начинается с того места, где закончилось руководство Вызов хранимой процедуры с параметром OUTPUT в Node.js.
Как использовать поток Node.js для обработки больших наборов результатов
Поток позволяет эффективно обрабатывать большой набор результатов, обрабатывая его построчно, а не загружая его в память сразу.
Поток полезен при обработке больших наборов результатов из SQL Server без использования большого объема памяти сервера.
Ниже описаны шаги по использованию потока:
Сначала подключитесь к SQL Server :
const pool = await sql.connect(config);
Во-вторых, создайте объект Request, который представляет запрос, выполняемый к SQL Server, и включает потоковую передачу:
const request = new sql.Request(pool); request.stream = true;
В-третьих, обрабатывайте данные по мере их поступления. Для этого используется метод on() объекта Request. Метод request.on() обрабатывает различные события, которые происходят во время выполнения запроса, когда поток включен:
- набор записей: срабатывает, когда доступны метаданные столбцов.
- строка: срабатывает для каждой строки в наборе результатов.
- ошибка: срабатывает при возникновении ошибки.
- done: срабатывает после завершения выполнения запроса.
Например, ниже показано, как обрабатывать каждую строку данных по мере их поступления с помощью request.on() с событием строки:
request.on('row', row => { console.log('Row:', row); });
Пример потоковой передачи данных в файл CSV
Мы покажем вам, как запросить данные из таблицы Authors и передать их напрямую в файл, чтобы избежать загрузки всего в память:
Шаг 1. Создайте новый файл с именем stream.js в каталоге проекта.
Шаг 2. Определите функцию exportAuthorsToCSV, которая экспортирует все строки из таблицы Authors в CSV-файл:
import fs from 'fs'; import sql from 'mssql'; import { config } from './config.js'; const exportAuthorsToCSV = async(csvFilename) => { try { // Create a write stream for the CSV file const writeStream = fs.createWriteStream(csvFilename); // Connect to the database const pool = await sql.connect(config); // Create a new request with streaming enabled const request = new sql.Request(pool); request.stream = true; // Execute the query request.query('SELECT * FROM Authors ORDER BY FirstName'); // Event handlers for the streaming request.on('recordset',(columns) => { let header = ''; for(const column in columns) { header += `${column},`; } // remove the last comma(,) header = header.slice(0, -1); // write the header writeStream.write(header + '\n'); }); // Process each row when it is arrived request.on('row',({ AuthorID, FirstName, LastName, BirthDate }) => { const csvRow = `${AuthorID},${FirstName},${LastName},${BirthDate.toLocaleDateString()}`; writeStream.write(csvRow + '\n'); }); // Error handlers for the request request.on('error',(err) => { console.error('Error:', err); writeStream.end(); }); // Event handler for when the query is done request.on('done',(result) => { console.log('Query done. Rows affected:', result.rowsAffected); writeStream.end(); }); } catch(err) { console.error(err); } }; export { exportAuthorsToCSV };
Как это работает.
Сначала импортируйте объекты fs, sql и config из модулей fs, mssql и config.js соответственно.
import fs from 'fs'; import sql from 'mssql'; import { config } from './config.js';
Во-вторых, определите функцию exportAuthorsToCSV, которая принимает имя файла CSV:
const exportAuthorsToCSV = async(csvFilename) => { //... };
В-третьих, создайте поток записи для CSV-файла:
const writeStream = fs.createWriteStream(csvFilename);
В-четвертых, подключитесь к SQL Server, используя предоставленный объект конфигурации.
const pool = await sql.connect(config);
Обратите внимание, что объект конфигурации содержит необходимые параметры для подключения к SQL Server, включая имя пользователя, пароль, сервер и имя базы данных:
В-пятых, создайте новый запрос с включенной потоковой передачей:
const request = new sql.Request(pool); request.stream = true;
В-шестых, выполните запрос, который извлекает данные из таблицы Authors:
request.query('SELECT * FROM Authors ORDER BY FirstName');
В-седьмых, запишите заголовок CSV-файла один раз в обработчике событий набора записей:
request.on('recordset',(columns) => { let header = ''; for(const column in columns) { header += `${column},`; } // remove the last comma(,) header = header.slice(0, -1); // write the header writeStream.write(header + '\n'); });
Как это работает.
- Инициализируйте заголовок пустой строкой.
- Выполните итерацию по свойствам объекта columns с помощью цикла for…in и объедините имена свойств(AuthorID, FirstName, LastName и BirthDate) в одну строку. Обратите внимание, что объект columns содержит все поля в таблице Authors, включая AuthorID, FirstName, LastName и BirthDate.
- Удалите последнюю запятую(,) из строки заголовка с помощью метода slice().
- Запишите заголовок в CSV-файл, вызвав метод write() объекта writeStream.
Восьмое, записывайте каждую строку в CSV-файл, когда она поступает в обработчик событий строки:
request.on('row',({ AuthorID, FirstName, LastName, BirthDate }) => { const csvRow = `${AuthorID},${FirstName},${LastName},${BirthDate.toLocaleDateString()}`; writeStream.write(csvRow + '\n'); });
Девятое, если произошла ошибка, выведите ее на консоль и завершите поток в обработчике событий ошибки:
request.on('error',(err) => { console.error('Error:', err); writeStream.end(); });
В-десятых, выведите сообщение на консоль и завершите поток в обработчике событий done:
request.on('done',(result) => { console.log('Query done. Rows affected:', result.rowsAffected); writeStream.end(); });
Одиннадцатое, выведите сообщение об ошибке на консоль в блоке catch:
console.error(err);
Наконец, экспортируйте функцию exportAuthorsToCSV.
Шаг 3. Измените index.js для использования функции exportAuthorsToCSV:
import { exportAuthorsToCSV } from './stream.js'; exportAuthorsToCSV('data/output.csv');
Как это работает.
Сначала импортируйте функцию exportAuthorsToCSV из модуля stream.js.
import { exportAuthorsToCSV } from './stream.js';
Во-вторых, вызовите функцию exportAuthorsToCSV() для экспорта данных об авторе в CSV-файл, расположенный по адресу data/output.csv:
exportAuthorsToCSV('data/output.csv');
Шаг 4. Откройте терминал и выполните следующую команду для запуска файла index.js:
npm start
Если программа отработает успешно, вы увидите новый выходной файл output.csv в каталоге данных:
AuthorID,FirstName,LastName,BirthDate 2,Agatha,Christie,9/15/1890 9,Charles,Dickens,2/7/1812 22,Emily,Bronte,7/30/1818 ...
Краткое содержание
- Используйте поток для эффективной обработки больших наборов результатов.
- Установите свойство stream объекта Request на true, чтобы включить потоковую передачу.
- Используйте метод request.on() для обработки событий, возникающих во время выполнения запроса после включения потоковой передачи.