Как разработчик JavaScript, работа с файлами CSV или TSV может быть чрезвычайно громоздкой. Но что, если бы существовал более быстрый способ? Знаете ли вы, что PostgreSQL поддерживает потоковую передачу данных непосредственно в таблицу и из нее?
JSONL, да? Что?
Когда вы сталкиваетесь с задачей импорта больших объемов данных, вариантами по умолчанию обычно являются файлы .csv или .tsv (или .xlsx, если вы чувствуете себя более предприимчивым!). Как разработчики JavaScript, мы чувствуем себя комфортно, работая с JSON и объектами. Но слышали ли вы о JSONL?
Что такое JSONL?
JSONL — это просто версия объектов JSON, разделенных строками. Каждая строка в файле JSONL представляет собой отдельный объект JSON, что упрощает анализ и обработку данных. Это делает его идеальным форматом для данных, которые необходимо обрабатывать в режиме реального времени или в потоковом режиме.
В приведенном ниже примере у нас есть простое экспресс-приложение, которое мы хотим разрешить пользователю импортировать контакты из CRM.
Каждый контакт будет представлен в таком объекте.
{ "first_name": "Bob", "last_name: "Doe", "email": "[email protected]", "phone": "+14155555555" }
Чтобы создать файл JSONL, было бы просто выглядеть так.
{ "first_name": "Bob", "last_name": "Doe", "email": "[email protected]", "phone": "+14155555555"} { "first_name": "Jan", "last_name": "Doe", "email": "[email protected]", "phone": "+14155555556"} { "first_name": "Jon", "last_name": "Doe", "email": "[email protected]", "phone": "+14155555557"}
Где каждая новая строка представляет собой объект JSON с представлением каждого контакта.
На практике.
Мы собираемся создать простое веб-приложение, которое будет передавать эти данные напрямую в Postgres.
Шаг 1. Создайте базу данных PostgreSQL
CREATE DATABASE my_data;
Шаг 2. Создайте таблицу базы данных PostgreSQL с названием contact
CREATE TABLE contacts ( first_name VARCHAR(255), last_name VARCHAR(255), email VARCHAR(255), phone VARCHAR(255) );
Шаг 3. Настройте среду Node.js
Прежде чем вы сможете начать работать с JSONL, вам необходимо настроить среду Node.js. Для этого вам необходимо установить Node.js и NPM (диспетчер пакетов Node) на свой компьютер. Вы можете скачать Node.js с официального сайта Node.js.
npm init
затем установите необходимые пакеты
npm i express npm i pg // for connecting to postgres npm i pg-copy-streams // for working with streams
Шаг 4. Создайте экспресс-приложение, которое будет принимать массовые данные
const express = require('express'); const { Pool } = require('pg'); const { copyFrom } = require('pg-copy-streams'); const app = express(); // create a pool of Postgres connections // this example is connecting to a local postgres database. This should be adjusted to fit your needs. const pool = new Pool({ connectionString: "postgres://username:password@localhost:5432/mydatabase", ssl: true }); // handle POST requests to bulk import data into the contacts table app.post('/contacts', async (req, res) => { const data = req.body; // assuming the request body contains JSONL data const client = await pool.connect(); try { // split the JSONL data into separate lines and parse each line as JSON const lines = data.split('\n'); const values = lines.map(line => JSON.parse(line)); // use a transaction to perform the bulk import await client.query('BEGIN'); const query = 'COPY contacts (first_name, last_name, email, phone) FROM STDIN (FORMAT JSON)'; const copyStream = client.query(copyFrom(query)); values.forEach(row => copyStream.write(JSON.stringify(row) + '\n')); copyStream.end(); await client.query('COMMIT'); // send a response to the client res.sendStatus(201); } catch (err) { console.error(err); await client.query('ROLLBACK'); res.sendStatus(500); } finally { client.release(); } }); app.listen(3000, () => console.log('App listening on port 3000'));
Шаг 5. Перейдите к своему любимому HTTP-клиенту (Postman, Thunder Client)
Создайте запрос POST к http://localhost:3000/contacts с необработанным телом данных JSON.
{ "first_name": "Bob", "last_name": "Doe", "email": "[email protected]", "phone": "+14155555555"} { "first_name": "Jan", "last_name": "Doe", "email": "[email protected]", "phone": "+14155555556"} { "first_name": "Jon", "last_name": "Doe", "email": "[email protected]", "phone": "+14155555557"}
И ПОСТ!
Такой подход снова сделал работу с Bulk Inserts быстрой и увлекательной! Попробуйте это в своем следующем проекте!