Автор оригинала: Janith Kasun.
Вступление
В этой статье мы обсудим, как интегрировать PostgreSQL с Node.js.
Чтобы лучше следовать этой статье, мы рекомендуем вам предыдущий опыт использования Node.js и SQL-заявлений. Мы будем использовать простой синтаксис JavaScript ES6 в этой статье.
Есть несколько разных клиентов, которые вы можете использовать для интеграции PostgreSQL с Node.js. В этой статье мы будем использовать Узел-postgres
модуль. Это популярный и зрелый модуль по сравнению с другими клиентами PostgreSQL.
Кроме того, вы можете использовать PostgreSQL с помощью orm, как Sequelize также. Но мы не будем использовать такое модуль ORM в этой статье. Вместо этого мы будем использовать простые запросы SQL, которые вы можете построить для более сложных взаимодействий баз данных.
Postgresql.
PostgreSQL это популярная база данных SQL. Он был в активном развитии за последние 30+ лет и считается одним из самых передовых реляционных баз данных там. PostgreSQL также легко учиться и настроить по сравнению с другими доступными реляционными базами данных. Из-за его свободной и открытой исходной природы это популярный выбор среди стартапов.
PostgreSQL – это кроссплатформенная база данных, которая работает на всех основных операционных системах. Создание конфигурации и доступа/базы данных слегка отличается между операционными системами.
В этой статье мы будем использовать Ubuntu 18.04, которая является популярной платформой Linux и включает PostgreSQL по умолчанию. Некоторые шаги могут быть немного отличными, если вы используете другую операционную систему.
Конфигурация проекта
Давайте начнем с простым простым проектом Node.js с настройками по умолчанию:
$ npm init -y
Тогда давайте будем использовать NPM
установить Узел-postgres
Модуль, который будет использоваться для подключения и взаимодействия с Postgres:
$ npm install --save pg
Реализация трудных операций
С нашим загрузочным проектом давайте пойдем вперед и настройте базу данных. После этого мы напишем некоторые основные функциональные возможности Crud.
Конфигурация базы данных
Как и во всех реляционных базах данных, мы начнем, создавая его и подключаемое к нему. Вы можете использовать клиент на основе CLI или GUI для этого. Поскольку очень просто настроить сквозь CLI, мы будем делать только это.
Для Ubuntu по умолчанию PSQL
Команда войдет в CLI. PostgreSQL создаст пользователь под названием Postgres
Чтобы получить доступ к базе данных на платформах на основе Linux. Таким образом, мы можем использовать следующую команду для входа в систему как Postgres
Пользователь:
$ sudo -i -u postgres
Затем введите CLI, запустив:
$ psql
Вы должны увидеть командную оболочку, аналогичную этому:
Для просмотра в настоящее время существующих баз данных давайте будем использовать \ Список
или \ l
команда:
И теперь, давайте создадим наших собственных, используя запрос SQL:
CREATE DATABASE testdb;
Запустив эту команду, мы создаем testdb
База данных и встреченная с выходом, подтверждающая нашу команду:
CREATE DATABASE
Поскольку база данных создана, теперь мы можем получить доступ к ней. Пока PostgreSQL создает по умолчанию Postgres
Пользователь, пароль не устанавливается по умолчанию. Если вы хотите установить свой пароль (а не оставить его пустым), используйте \ Password
команда:
С помощью вашего набора паролей мы готовы использовать базу данных в нашем проекте.
Подключение к базе данных
У вас есть два варианта, которые вы можете подключиться к серверу PostgreSQL с Узел-postgres
модуль. Одним из вариантов является использование одного клиента. Другой метод – использовать пул соединения. Однако, если ваше приложение очень часто использует базу данных, бассейн будет лучшим вариантом, чем использование одного клиента.
Подключение к базе данных с использованием Узел-postgres
Модуль можно сделать двумя способами – использование Одиночный клиент и используя Пул соединения Отказ
Мы посмотрим, как использовать пул соединения для подключения к базе данных позже в этой статье. На данный момент давайте подключаемся к базе данных с помощью одного клиента для краткости и простоты:
const { Client } = require('pg'); const client = new Client({ user: 'postgres', host: 'localhost', database: 'testdb', password: '1234abcd', port: 5432, }); client.connect();
Здесь мы вручную настроили параметры. Однако вы можете подключиться к базе данных, не передавая ни одного из них:
const { Client } = require('pg'); const client = new Client(); client.connect();
Но опять же, узел нужно знать Как Для подключения к базе данных, поэтому мы предоставим их через переменные среды:
PGUSER=dbuser PGHOST=database.server.com PGPASSWORD=secretpassword PGDATABASE=mydb PGPORT=3211
Если вы не настроили их сами, модуль будет использовать значения по умолчанию:
PGHOST='localhost' PGUSER=process.env.USER PGDATABASE=process.env.USER PGPASSWORD=null PGPORT=5432
На Linux, process.env.user
будет держать значение для текущего пользователя, который вошел в систему.
Создание таблиц
С помощью базы данных PREDED для вставки данных, давайте создадим несколько таблиц для хранения наших данных в. Как и во всех базах данных SQL, мы будем использовать Создать таблицу
запрос:
CREATE TABLE [table_name] ( [column1] [datatype], [column2] [datatype], [column3] [datatype], .... );
Стол состоит из Колонны и каждый столбец имеет тип данных. Например, Имя
колонна будет иметь varchar
Как тип данных, который представляет строку переменного размера.
Если вы хотите узнать больше о поддерживаемых типах данных, PostgreSQL Документация Перечисляет их красиво.
Это, как говорят, мы можем использовать этот запрос для создания таблицы в базе данных:
const query = ` CREATE TABLE users ( email varchar, firstName varchar, lastName varchar, age int ); `;
Чтобы на самом деле запустить этот запрос против базы данных, мы используем Запрос ()
Функция из клиент
объект, который мы настроили до:
client.query(query, (err, res) => { if (err) { console.error(err); return; } console.log('Table is successfully created'); client.end(); });
Примечание: Не забудьте конец ()
Ваше подключение к клиенту после завершения запроса.
Запуск этого кода создаст наш стол и распечатает:
Table is successfully created
Это также может быть достигнуто с использованием обещаний и Async/await
Отказ Поскольку вызов базы данных может потерпеть неудачу, это имеет больше смысла использовать обещания:
client .query(query) .then(res => { console.log('Table is successfully created'); }) .catch(err => { console.error(err); }) .finally(() => { client.end(); });
Как вы можете видеть в примере, мы можем использовать наконец-то блок, чтобы закрыть соединение с базой данных. Так что даже если запрос бросил Err
Соединение будет закрыто.
В качестве альтернативы, мы можем использовать Async/await
Синтаксис также:
try { const res = await client.query(query); console.log('Table is successfully created'); } catch (err) { console.log(err.stack); } finally { client.close(); }
Все эти подходы должны дать тот же результат:
Table is successfully created
Чтобы проверить это, давайте будем использовать PSQL
Интерфейс командной строки для проверки БД. Откройте терминал, запустите оболочку с помощью PSQL
и выберите базу данных, используя \ C [База данных]
команда. \ C
Снаряжение для \ connect
:
\c testdb
Затем вы можете перечислить таблицы в базе данных testdb
Берегите \ dt
команда:
Вы также можете запросить конкретные таблицы, предоставив их имена:
testdb=# \dt FOO
Этот запрос будет отображать таблицу с именем Foo
Отказ
Создание/вставка данных
Мы можем использовать SQL Вставить в
Заявление для вставки данных в таблицу:
INSERT INTO [table_name] ([column1], [column2], [column3], ...) VALUES ([value1], [value2], [value3], ...);
Чтобы сделать этот запросбен, давайте вставьте наши собственные значения и построить запрос:
const query = ` INSERT INTO users (email, firstName, lastName, age) VALUES ('[email protected]', 'john', 'doe', 21) `;
И, наконец, давайте запустим запрос против базы данных:
client.query(query, (err, res) => { if (err) { console.error(err); return; } console.log('Data insert successful'); client.end(); });
Примечание: Так же, как в прошлый раз, эта функция может быть написана с помощью Async/await
синтаксис. Эти дополнительные примеры опущены для краткости.
Запуск этого кода вставит пользователя в нашу базу данных и распечатать:
Data insert successful
Чтобы проверить это, в нашем testdb
База данных, запустите Выберите
утверждение:
SELECT * from users;
Мы можем, очевидно, видим, что пользователь действительно был успешно создан:
Получение/выбор данных
Чтобы получить данные из базы данных Выберите
Заявление используется:
SELECT [column1], [column2], ... FROM [table_name] WHERE [condition];
Вы можете выбрать определенные столбцы, указав их или выбираете все поля таблицы с помощью *
подстановочный знак Необязательно, вы можете получить креатив с большим количеством условных условий, используя Где
утверждение.
Здесь мы выбираем все строки и все столбцы из Пользователи
база данных:
const query = ` SELECT * FROM users `;
Теперь, чтобы запустить этот запрос против базы данных, мы будем использовать клиент
очередной раз:
client.query(query, (err, res) => { if (err) { console.error(err); return; } for (let row of res.rows) { console.log(row); } client.end(); });
Запуск этого кода даст:
{ email: '[email protected]', firstname: 'john', lastname: 'doe', age: 21 } { email: '[email protected]', firstname: 'anna', lastname: 'dias', age: 35 }
Этот запрос возвращает Все Пользователи добавляются в базу данных. Вы также можете отфильтровать пользователей по их полям.
Например, если мы хотели вернуть всех пользователей моложе 30, мы добавили Где
пункт:
const query = ` SELECT * FROM users WHERE age<30 `;
А потом у нас будет работать против базы данных:
client.query(query, (err, res) => { if (err) { console.error(err); return; } for (let row of res.rows) { console.log(row); } client.end(); });
Запуск этого кода даст:
{ email: '[email protected]', firstname: 'john', lastname: 'doe', age: 21 }
Обновление данных
Чтобы обновить данные, которые уже существуют, мы можем использовать Обновить
утверждение:
UPDATE [table_name] SET [column1] = [value1], [column2] = [value2], ... WHERE [condition];
Вы можете установить каждое обновленное значение для каждого столбца с Установить
ключевое слово. После Где
Пункт, вы можете определить состояние того, какие записи должны быть обновлены.
Давайте заполним наш запрос:
const query = ` UPDATE users SET age = 22 WHERE email = '[email protected]' `;
Теперь давайте запустим запрос против базы данных:
client.query(query, (err, res) => { if (err) { console.error(err); return; } if (err) { console.error(err); return; } console.log('Data update successful'); client.end(); });
Запуск этого куска кода обновит записи, удовлетворяющие Где
Пункт и распечатать:
Data update successful
Чтобы проверить, давайте проверим нашу базу данных:
Удаление данных
Наконец, чтобы удалить данные, мы можем использовать Удалить
утверждение:
DELETE FROM [table_name] WHERE [condition];
Будьте осторожны с этим утверждением, так как вы можете случайно удалить больше, чем вы стремитесь.
Давайте заполним наш запрос:
const query = ` DELETE FROM users WHERE email = '[email protected]' `;
И, наконец, запустите его против базы данных:
client.query(query, (err, res) => { if (err) { console.error(err); return; } if (err) { console.error(err); return; } console.log('Data delete successful'); client.end(); });
Запуск этого кода удалит запись, удовлетворяющий Где
Пункт и распечатать:
Data delete successful
Чтобы проверить, давайте посмотрим на базу данных:
Объединение
Если ваше приложение часто используется база данных, используя однократное клиентское соединение с базой данных, вероятно, замедлит приложение, когда у вас есть много пользовательских запросов. Самый простой и удобный способ решить эту проблему – использовать соединительный пул.
Обычно, когда новый клиент подключается к базе данных, процесс установления соединения и аутентификации занимает около 20-30 миллисекунд. Это значимо, когда вы используете больше запросов, ведущих к секундам задержки, что, вероятно, в конечном итоге будет неудовлетворительным опытом для конечного пользователя.
Кроме того, PostgreSQL Server может обрабатывать только ограниченное количество клиентов в определенное время, которое будет зависеть от вашей памяти сервера. Так что, если 100 запросов продолжаются через секунду – это ограничение может сбиться с вашим сервером.
Кроме того, клиент может обрабатывать только один запрос одновременно для одного соединения, которое дополнительно замедляет вещи.
В такой ситуации, вы можете использовать PG-Pool
модуль, чтобы решить это.
Создание пула
Первый импорт Бассейн
Класс от PG
модуль:
const { Pool } = require('pg');
Затем давайте создадим новый объект бассейна:
const pool = new Pool({ user: 'postgres', host: 'localhost', database: 'testdb', password: '1234abcd', port: 5432, });
Если вы не настраиваете имя пользователя, хост и другие свойства, вам придется определить переменные среды для них в файле конфигурации. Это почти так же, как при настройке одного клиента.
Далее давайте определим обработчик ошибок для пула. Если есть какие-либо ошибки, бросающие из бассейна, обратный вызов в этом событии будет уволен:
pool.on('error', (err, client) => { console.error('Error:', err); });
Это охватывает нас в случае ошибки сети.
Затем, используя Бассейн
Объект, мы подключаемся к базе данных и используем клиент
В этом бассейне выполнить запрос:
const query = ` SELECT * FROM users `; pool.connect((err, client, done) => { if (err) throw err; client.query(query, (err, res) => { done(); if (err) { console.log(err.stack); } else { for (let row of res.rows) { console.log(row); } } }); });
Это должно дать:
{ email: '[email protected]', firstname: 'john', lastname: 'doe', age: 21 } { email: '[email protected]', firstname: 'anna', lastname: 'dias', age: 35 }
Опять же, это имеет больше смысла использовать обещания в этом случае:
pool.connect() .then((client) => { client.query(query) .then(res => { for (let row of res.rows) { console.log(row); } }) .catch(err => { console.error(err); }); }) .catch(err => { console.error(err); });
Или даже Async/await
синтаксис:
(async () => { try { const client = await pool.connect(); const res = await client.query(query); for (let row of res.rows) { console.log(row); } } catch (err) { console.error(err); } })();
Использование курсора для чтения больших запросов
Обычно данные, полученные от запроса, загружаются прямо в память. Чем больше набор данных, тем выше будет использование памяти.
Поэтому, когда вы пытаетесь запрашивать большой набор данных, который может содержать тенденцию тысяч записей – это очень неэффективно загружать все это в память и часто, это просто невозможно. Курсор может помочь вам в такой ситуации, извлечение ограниченного количества записей одновременно.
В некотором смысле использования курсора аналогична потоковым данным, поскольку вы получите доступ к нему последовательно в небольших блоках. Для того, чтобы использовать курсор, мы должны установить PG-курсор
Сначала модуль:
$ npm install --save pg pg-cursor
Мы будем проходить Новый курсор
к Запрос ()
функция. Курсор
Не на самом деле не извлекает никакой информации, пока не укажем предел, используя Читать ()
Метод:
const { Pool } = require('pg'); const Cursor = require('pg-cursor'); const pool = new Pool({ user: 'postgres', host: 'localhost', database: 'testdb', password: '1234abcd', port: 5432, }); (async () => { const client = await pool.connect(); const query = 'SELECT * FROM users'; const cursor = await client.query(new Cursor(query)); cursor.read(1, (err, rows) => { console.log('We got the first row set'); console.log(rows); cursor.read(1, (err, rows) => { console.log('This is the next row set'); console.log(rows); }); }); })();
Курсор
‘s Читать ()
Метод позволяет нам определить, сколько строк, которые мы хотим получить от текущего Курсор
пример. В этом примере для простоты мы ограничили строки для одной записи. Затем мы прочитали другой набор строк после этого.
Если вы достигли конца строк в базе данных, Ряды
Массив будет длиной 0
Отказ
Заключение
PostgreSQL – это действительно популярная, бесплатная, открытая реляционная база данных. Узел-postgres
Модуль представляет собой широко используемый и созревший модуль, который мосты Node.js к PostgreSQL.
В этой статье мы создали базу данных PostgreSQL и разработали базовую функциональность Crud через простой сценарий Node.js. Затем мы изучили поддержку объединения и использование курсоров, чтобы ограничить полученные данные.
Как всегда, исходный код доступен на Github Отказ