Skip to main content
node-postgres (пакет pg) — самый популярный драйвер Postgres для Node.js. В этом руководстве вы подключитесь к ClickHouse Managed Postgres через pg.Pool с полной проверкой TLS-сертификата, создадите две таблицы, переведёте деньги между счетами в рамках транзакции и организуете отдачу данных с помощью небольшого сервера на node:http.

Предварительные требования

  • Node.js версии 20.6 или новее (для встроенного флага --env-file). Это руководство проверено на Node.js 24.21.0 и pg 8.23.1.
  • Аккаунт ClickHouse Cloud
  • psql для создания базы данных

Создание сервиса ClickHouse Managed Postgres

В консоли ClickHouse Cloud нажмите New service и выберите Postgres. Инстанс будет готов через несколько минут. Пошаговые инструкции приведены в кратком руководстве.

Получите сведения о подключении

Нажмите Connect на левой боковой панели вашего сервиса. Выбрав Directly, скопируйте URL подключения на вкладке url. Параметр Use SSL оставьте выключенным: приложение передаёт CA‑сертификат в коде, а не в URL (см. Настройка пула соединений). В этом руководстве используется прямое подключение к Postgres через порт 5432. Долго работающий сервер Node.js и так поддерживает собственный пул соединений через pg.Pool, поэтому дополнительный пулер перед Postgres ему не нужен. Если вы запускаете много процессов или serverless-функций, используйте вместо этого встроенный PgBouncer (см. Использование PgBouncer). Затем скачайте CA‑сертификат для своего инстанса. Включите Use SSL и нажмите Download CA certificate или перейдите в Settings → CA Certificate → Download CA certificate. У каждого инстанса свой уникальный сертификат.

Настройка проекта

Создайте проект и установите pg:
Добавляете в существующее приложение?Пропустите mkdir и npm init -y. Выполните в своём проекте npm install pg, а затем переходите к разделу Создание базы данных.
Примеры в этом руководстве написаны как ES-модули с расширением .mjs, поэтому они работают независимо от того, какая система модулей указана в вашем package.json: CommonJS или ES-модули.

Создайте базу данных

Переместите скачанный файл <service-name>-ca-certificate.pem в каталог проекта и переименуйте его в ca-certificate.pem. Затем создайте базу данных для приложения:
Создайте файл .env и укажите в нём скопированный URL подключения, заменив имя базы данных на guide_nodejs, а также путь к сертификату:
.env
Если пароль содержит такие символы, как @, / или #, закодируйте их в URL с помощью процентного кодирования (percent-encoding).

Настройка пула соединений

Создайте файл db.mjs. Он экспортирует единый пул, общий для всего остального приложения:
db.mjs
Передача ssl: { ca } эквивалентна sslmode=verify-full: pg проверяет, что сертификат сервера подписан CA вашего инстанса и соответствует имени хоста. По умолчанию rejectUnauthorized имеет значение true; не меняйте его на false.
Не смешивайте ssl с параметрами SSL в URLЕсли DATABASE_URL содержит sslmode или sslrootcert, pg формирует настройки TLS на основе URL и игнорирует объект ssl. Например, URL, оканчивающийся на ?sslmode=verify-full без sslrootcert, переопределяет ваш ca, и соединение завершается ошибкой unable to verify the first certificate. Если вы передаёте ssl в коде, не указывайте параметры SSL в DATABASE_URL.Также учтите следующее:
  • Если не задан ни объект ssl, ни sslmode в URL, pg не использует TLS и не проверяет сервер.
  • pg считывает PGHOST, PGUSER, PGPASSWORD и аналогичные переменные, но не считывает PGSSLROOTCERT. Поэтому одних только переменных с вкладки env модального окна Connect недостаточно для проверки сервера.
  • Если вы предпочитаете хранить всё в URL, можно использовать с pg и тот URL, который модальное окно Connect показывает при включённом параметре Use SSL, например ...?sslmode=verify-full&sslrootcert=ca-certificate.pem. В этом случае удалите параметр ssl и учтите, что путь sslrootcert вычисляется относительно каталога, из которого вы запускаете Node.js.

Создание схемы

Создайте файл setup.mjs. Он создаёт таблицы, вставляет два аккаунта с помощью параметризованных запросов, а затем считывает их:
setup.mjs
Всегда передавайте значения как параметры ($1, $2, …), а не встраивайте их в строку SQL с помощью конкатенации. pg отправляет их отдельно от текста запроса, что защищает от SQL-инъекций. Массивы JavaScript преобразуются в массивы Postgres, как в запросе с ANY($1). Запустите его:
pg возвращает значения типа numeric (и bigint) в виде строк, чтобы избежать потери точности. Если вам нужны числа, явно преобразуйте их.

Выполнение запросов в транзакции

Транзакция должна выполняться в рамках одного соединения, поэтому получите клиент из пула с помощью pool.connect и обязательно освобождайте его после использования. Создайте файл transfer.mjs:
transfer.mjs
Не используйте pool.query для выполнения операторов внутри транзакции: каждый вызов pool.query может выполняться через другое соединение.

Отдача данных по HTTP

Создайте файл server.mjs. Он отдаёт аккаунты и переводы в формате JSON на порту 3107, принимает новые переводы и корректно завершает работу по сигналу SIGINT (Ctrl+C) или SIGTERM:
server.mjs
Вызывайте pool.end один раз — при завершении процесса, а не после каждого запроса. Метод дожидается, пока все выданные клиенты вернутся в пул, а затем закрывает все соединения.

Проверка

Запустите сервер:
Во втором терминале выполните перевод, а затем попробуйте выполнить перевод, превышающий остаток на счёте, и перевод на несуществующий счёт:
Третий перевод уже успел списать средства со счёта alice, когда произошёл сбой, но ROLLBACK отменил это списание. Откройте в браузере http://localhost:3107/accounts, чтобы посмотреть балансы. Ответ будет выглядеть примерно так:
Чтобы убедиться, что соединение использует TLS с проверкой сертификата, выполните запрос к pg_stat_ssl:
Если указать в DATABASE_CA_CERT любой другой сертификат, установить соединение не удастся: появится ошибка unable to verify the first certificate. Это подтверждает, что сертификат сервера действительно проверяется. Наконец, остановите сервер, нажав Ctrl+C. Он выведет SIGINT received, shutting down, а затем Pool closed. Данные также можно просмотреть в консоли. Откройте консоль SQL, разверните базу данных guide_nodejs и откройте таблицу accounts:

Использование PgBouncer

Чтобы подключаться через встроенный PgBouncer, выберите via PgBouncer в модальном окне Connect и укажите порт 6432 в DATABASE_URL. Изменять код не нужно, а CA‑сертификат остаётся прежним. PgBouncer работает в режиме пулинга транзакций (transaction pooling), поэтому каждая транзакция может выполняться в отдельном соединении с Postgres. При использовании pg:
  • Параметризованные запросы, именованные подготовленные операторы (pool.query({ name, text, values })) и транзакции через pool.connect работают так, как показано в этом руководстве.
  • SQL-команды PREPARE и EXECUTE, а также настройки сеанса, заданные с помощью SET, не сохраняются между транзакциями. Вместо этого используйте SET LOCAL внутри транзакции.
  • pg_stat_ssl показывает соединение между PgBouncer и Postgres, поэтому приведённый выше запрос для проверки TLS возвращает ssl: false. При этом соединение вашего приложения с PgBouncer по-прежнему проверяется: с неверным CA‑сертификатом подключение завершится такой же ошибкой.

Дальнейшие шаги