Коли ви працюєте з великими наборами даних, ефективний імпорт мільйонів записів у базу даних може бути складним завданням.
Ця стаття розглядає ефективний підхід, використовуючи Node.js, PostgreSQL та CSV-файли, з використанням потокового оброблення (streaming). Метою є ефективно вставити один мільйон записів у базу даних PostgreSQL, при цьому контролюючи використання ресурсів.
Для тих, хто поспішає побачити код, ви можете знайти його тут: https://github.com/vdelacou/postgresql-bulk-data-generator
Ключові концепти
- Потокове оброблення (Streaming): Використання потоків для послідовного читання та запису великих файлів замість повного завантаження їх у пам'ять.
Чому цей підхід?
Цей підхід використовує асинхронну природу Node.js у поєднанні з командою PostgreSQL COPY
для масового імпорту даних. Основні переваги включають:
- Продуктивність: Команда
COPY
оптимізована для масових вставок. - Ефективність пам'яті: Дані передаються через потоки, що дозволяє уникати надмірного використання пам'яті.
Імпорт CSV даних
Команда COPY
ефективно завантажує дані з CSV файлу у вказану таблицю бази даних. Нижче наведена реалізація, яка використовує ефективну конвеєрну структуру потоків:
const copyCsvToTable = async (client: PoolClient): Promise => {
const fileStream = createReadStream('./data.csv');
const pgStream = client.query(from(`COPY consumers (name,email) FROM STDIN WITH (FORMAT csv, HEADER true)`));
try {
await pipeline(fileStream, pgStream);
logger.info('Копіювання CSV даних завершено успішно');
} catch (error) {
logger.error('Помилка під час копіювання:', error);
throw error;
}
};
Детальні кроки
- Відкриття потоку файлу: Використовуйте функцію
createReadStream
для відкриття потоку читання для CSV файлу. - Налаштування потоку PostgreSQL: Використовуйте команду
COPY
для підготовки PostgreSQL до отримання даних. Методfrom
з бібліотекиpg-copy-streams
надає можливість потоку. - Потокова передача даних: Використовуйте утиліту
pipeline
для з’єднання потоку файлу з потоком PostgreSQL. Це дозволяє передавати дані безпосередньо з файлу в базу даних.
Переваги потокового оброблення з COPY
- Ефективність: Команда
COPY
обробляє файл як безперервний потік, що значно знижує накладні витрати порівняно з вставкою кожного рядка окремо. - Обробка помилок: Блок
try-catch
забезпечує реєстрацію будь-яких помилок під час процесу потокової передачі та їх повторну генерацію для належної обробки.
Додатково: Генерація фальшивого CSV файлу
Першим кроком є створення CSV файлу з фіктивними даними. Цей файл буде використовуватися як джерело даних для імпорту в PostgreSQL.
const generateRow = (): [string, string] => [
faker.person.fullName(),
faker.internet.email(),
];
const generateCsvFile = async (): Promise => {
const csvFile = Bun.file('./data.csv');
if (await csvFile.exists()) {
await unlink('./data.csv');
}
const writer = csvFile.writer();
writer.write('name,email\n');
for (let i = 0; i < config.itemsCount; i++) {
const row = generateRow();
writer.write(`${row.join(',')}\n`);
}
writer.end();
};
Детальні кроки:
- Перевірка наявності існуючого файлу: Якщо CSV файл вже існує, його потрібно видалити для забезпечення чистого початку.
- Відкриття потоку запису: Використовуйте потік запису для послідовного запису даних у CSV файл.
- Генерація фіктивних даних: Використовуйте бібліотеку
faker
для створення реалістичних імен та електронних адрес для кожного рядка. - Запис даних у CSV: Записуйте кожен рядок у файл, розділяючи стовпці комами.
- Закриття потоку: Після запису всіх рядків закрийте потік для завершення файлу.
Висновок
Цей метод ефективно обробляє імпорт одного мільйона записів у PostgreSQL всього за 3 секунди!
З використанням потокового оброблення та обережним застосуванням можливостей PostgreSQL ви можете легко працювати з великими наборами даних.
Якщо ви прагнете масштабувати свої робочі процеси з даними, цей підхід стане надійною відправною точкою.
Спробуйте це: Модифікуйте код під ваш набір даних та базу даних. Бажаємо успіхів у програмуванні!
Перекладено з: Efficient Data Import in PostgreSQL with Node.js