Рубрики
Без рубрики

Использование PostgreSQL с Node.js и Node-postgres

PostgreSQL – это действительно популярная, бесплатная, открытая реляционная база данных. Модуль Node-Postgres – это широко используемый модуль, который с ним узел мосты. В этой статье мы будем разрабатывать простые функциональные возможности Crud для базы данных PostgreSQL.

Автор оригинала: 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

Вы должны увидеть командную оболочку, аналогичную этому:

PostgreSQL PSQL Command

Для просмотра в настоящее время существующих баз данных давайте будем использовать \ Список или \ l команда:

PostgreSQL Список команд

И теперь, давайте создадим наших собственных, используя запрос SQL:

CREATE DATABASE testdb;

Запустив эту команду, мы создаем testdb База данных и встреченная с выходом, подтверждающая нашу команду:

CREATE DATABASE

Поскольку база данных создана, теперь мы можем получить доступ к ней. Пока PostgreSQL создает по умолчанию Postgres Пользователь, пароль не устанавливается по умолчанию. Если вы хотите установить свой пароль (а не оставить его пустым), используйте \ Password команда:

Изменение пароля PostgreSQL с помощью CLI

С помощью вашего набора паролей мы готовы использовать базу данных в нашем проекте.

Подключение к базе данных

У вас есть два варианта, которые вы можете подключиться к серверу 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 команда:

PostgreSQL списка таблиц

Вы также можете запросить конкретные таблицы, предоставив их имена:

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;

Мы можем, очевидно, видим, что пользователь действительно был успешно создан:

PostgreSQL, показывающий данные таблицы

Получение/выбор данных

Чтобы получить данные из базы данных Выберите Заявление используется:

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

Чтобы проверить, давайте проверим нашу базу данных:

PostgreSQL, показывающий данные таблицы

Удаление данных

Наконец, чтобы удалить данные, мы можем использовать Удалить утверждение:

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

Чтобы проверить, давайте посмотрим на базу данных:

PostgreSQL, показывающий данные таблицы

Объединение

Если ваше приложение часто используется база данных, используя однократное клиентское соединение с базой данных, вероятно, замедлит приложение, когда у вас есть много пользовательских запросов. Самый простой и удобный способ решить эту проблему – использовать соединительный пул.

Обычно, когда новый клиент подключается к базе данных, процесс установления соединения и аутентификации занимает около 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 Отказ