Гид по технологиям

Настройка PostgreSQL в Node.js с помощью Sequelize

7 min read База данных Обновлено 04 Jan 2026
Postgres в Node.js с Sequelize
Postgres в Node.js с Sequelize

Краткий план: подключите PostgreSQL к Node.js через Sequelize, настройте соединение через URI или параметры, опишите модели через DataTypes и выполняйте CRUD через методы ORM. В статье есть практические примеры, конфигурация для разработки и развёртывания, чек-листы, рекомендации по безопасности и советы по отладке.

Слон стоит в лесу среди деревьев

Sequelize — это ORM для Node.js, который предоставляет удобный API для реляционных баз данных, таких как PostgreSQL, MySQL, MariaDB, SQLite и другие. PostgreSQL — широко используемая открытая СУБД с богатым набором возможностей, хорошей безопасностью и масштабируемостью. В этой статье пошагово показано, как настроить PostgreSQL в проекте Node.js с помощью Sequelize, как определять модели, выполнять запросы и какие практики применять в продакшне.

О чём этот материал

  • как установить зависимости и драйверы
  • как подключиться к базе через URI или параметры
  • как описать модель и синхронизировать таблицу
  • примеры CRUD-операций через Sequelize
  • дополнительные рекомендации: безопасность, бэкапы, миграции, Docker, чек-листы

Шаг 1: установка зависимостей

Перед подключением к PostgreSQL нужно установить саму СУБД локально или использовать облачный сервис вроде ElephantSQL. Для локальной установки перейдите на официальный сайт PostgreSQL и скачайте дистрибутив для своей ОС. На macOS полезно использовать Homebrew: brew install postgresql

Альтернатива локальной установке — развёртывание контейнера PostgreSQL через Docker или использование управляемого сервиса.

Далее установите sequelize и драйвер для PostgreSQL в проект Node.js:

npm install sequelize
npm install pg pg-hstore

pg — официальный драйвер для PostgreSQL. pg-hstore нужен для сериализации типов hstore, если вы планируете их использовать.

Важные заметки:

  • держите версии sequelize и pg совместимыми по релизам
  • для TypeScript-проектов дополнительно устанавливайте типы и используйте sequelize-typescript или типовые объявления

Шаг 2: подключение к базе данных PostgreSQL

Создайте каталог конфигурации, например config, и файл db.js внутри него. В этом файле задаётся экземпляр Sequelize и функция тестирования соединения.

Пример простого файла config/db.js:

const { Sequelize } = require('sequelize')

// пример с параметрами подключения
const sequelize = new Sequelize('database', 'username', 'password')

// или используя URI из переменных окружения
// const sequelize = new Sequelize(process.env.POSTGRESQL_DB_URI)

const testDbConnection = async () => {
  try {
    await sequelize.authenticate()
    console.log('Соединение успешно установлено.')
  } catch (error) {
    console.error('Не удалось подключиться к базе данных:', error)
  }
}

module.exports = { sq: sequelize, testDbConnection }

Пояснения:

  • конструктор Sequelize принимает параметры: имя базы, пользователя, пароль, а также опционально объект с настройками
  • альтернативный способ — один строковый URI вида postgres://user:pass@host:port/dbname
  • метод authenticate() проверяет соединение без выполнения миграций

Рекомендации по конфигурации:

  • храните чувствительные данные в переменных окружения, а не в коде
  • в dev-режиме используйте .env и пакет dotenv, в продакшне — секреты платформы

Пример .env и использования в db.js:

// .env
POSTGRESQL_DB_URI=postgres://user:password@localhost:5432/mydb
// config/db.js
require('dotenv').config()
const { Sequelize } = require('sequelize')
const sequelize = new Sequelize(process.env.POSTGRESQL_DB_URI)

module.exports = { sq: sequelize }

Шаг 3: создание модели Sequelize

Создайте папку models и в ней файлы моделей. Название файла должно отражать сущность, например user.js или product.js.

Пример модели models/user.js:

const { sq } = require('../config/db')
const { DataTypes } = require('sequelize')

const User = sq.define('user', {
  email: {
    type: DataTypes.STRING,
    allowNull: false,
    primaryKey: true,
  },

  fullName: {
    type: DataTypes.STRING,
  },

  age: {
    type: DataTypes.INTEGER,
  },

  employed: {
    type: DataTypes.BOOLEAN,
    defaultValue: false,
  },
})

User.sync().then(() => {
  console.log('User модель синхронизирована')
})

module.exports = User

Пояснения по свойствам:

  • DataTypes задаёт типы столбцов
  • allowNull: false эквивалент NOT NULL
  • primaryKey: true делает поле первичным ключом
  • defaultValue задаёт значение по умолчанию

Метод sync имеет несколько режимов работы:

  • Model.sync() — создать таблицу, если её нет
  • Model.sync({ force: true }) — удалить таблицу и создать заново (опасно в проде)
  • Model.sync({ alter: true }) — попытаться привести таблицу в соответствие с моделью

В большинстве проектов в продакшне используют миграции вместо sync с force/alter, чтобы не потерять данные и иметь контроль версий схемы.

CRUD: создание, чтение, обновление, удаление

Все примеры ниже предполагают, что модель User импортирована и подключение уже инициализировано.

Сохранение данных:

const mike = await User.create({
  email: 'mike@example.com',
  fullName: 'Mike Smith',
  age: 30,
  employed: true,
})

Получение данных:

// найти всех пользователей
const users = await User.findAll()

// найти одного пользователя по условию
const mike = await User.findOne({ where: { email: 'mike@example.com' } })

Фильтрация через where:

const unemployed = await User.findAll({
  where: {
    employed: false,
  },
})

Обновление данных:

// массовое обновление
await User.update({ employed: true }, {
  where: {
    employed: false,
  },
})

// обновление через экземпляр
const userMike = await User.findOne({ where: { email: 'mike@example.com' } })
if (userMike !== null) {
  userMike.email = 'mike@example.org'
  await userMike.save()
}

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

await User.destroy({
  where: {
    email: 'mike@example.org',
  },
})

Важно: методы update и destroy применяются к записям, которые удовлетворяют условию where. Будьте осторожны с пустыми where, чтобы не удалить все записи.

Конфигурация для разработки: Docker и локальный Postgres

Пример docker-compose.yml для локальной разработки:

version: '3.8'
services:
  db:
    image: postgres:14
    restart: always
    environment:
      POSTGRES_USER: devuser
      POSTGRES_PASSWORD: devpass
      POSTGRES_DB: devdb
    ports:
      - '5432:5432'
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

После запуска docker compose up -d база будет доступна на localhost:5432 и вы сможете указать в .env URI postgres://devuser:devpass@localhost:5432/devdb

Использование управляемых сервисов: пример ElephantSQL

Если вы используете ElephantSQL или аналогичный провайдер, в панели управления вы получите строку подключения вида postgres://user:password@host:port/dbname

Используйте её в переменной окружения POSTGRESQL_DB_URI и подключайтесь в коде через new Sequelize(process.env.POSTGRESQL_DB_URI)

Миграции и контроль схемы

Для контроля версий схемы рекомендуется использовать систему миграций, например umzug вместе с sequelize-cli или сторонние инструменты. Миграции позволяют:

  • применять изменения шаг за шагом
  • откатывать изменения при ошибках
  • управлять схемой в командах разработки и CI/CD

Примерный рабочий процесс миграций:

  1. создать миграцию, описать ALTER/CREATE TABLE
  2. запустить миграции в staging и тестовой среде
  3. прогнать тесты и проверки целостности
  4. выполнить миграции в продакшне по окну обслуживания

Безопасность и жёсткое производство

Рекомендации по защите данных и соединения:

  • используйте SSL/TLS для соединений к базе в продакшне
  • применяйте принцип наименьших привилегий: отдельный пользователь для приложения с ограниченным набором прав
  • храните секреты в менеджере секретов или переменных окружения, не в репозитории
  • выполняйте регулярные бэкапы базы и проверяйте процедуры восстановления
  • логируйте и мониторьте медленные запросы и ошибки соединений
  • избегайте использования sync({ force: true }) в автоматических релизах

Когда Sequelize может не подойти

  • вам нужны сложные специфичные SQL-возможности, которые тяжело выразить через ORM
  • вы стремитесь к максимальной производительности в критичных местах, где ORM добавляет накладные расходы
  • коллектив предпочитает строго типизированные схемы и миграции на уровне TypeScript, тогда Prisma и титановые инструменты могут быть предпочтительнее

В таких случаях рассмотрите альтернативы: Prisma, TypeORM, Objection.js, Knex.js (query builder)

Альтернативные подходы

  • Prisma: современный ORM с генерацией типов для TypeScript, хорош для проектов с сильной статической типизацией
  • TypeORM: ORM с похожим API на Active Record / Data Mapper
  • Objection.js + Knex: ORM над query builder, удобен если нужен контроль SQL и гибкость
  • Чистый SQL через pg или query builder: для высокопроизводительных участков и простоты

Ментальные модели и эвристики

  • модели = проекция объектов приложения на таблицы/строки базы данных
  • миграции = скоординированные изменения схемы, которые должны быть идемпотентными и обратимыми
  • синхронизация в dev != миграции в prod
  • ORM упрощает CRUD, но не заменяет понимание SQL и индексов

Чек-листы

Для разработчика перед деплоем:

  • проверено ли подключение через переменные окружения
  • нет ли в коде sync({ force: true }) или других опасных вызовов
  • есть ли миграции для всех изменений схемы
  • настроены ли бэкапы и мониторинг

Для DevOps:

  • настроены ли секреты и SSL
  • проверены ли права пользователя БД
  • есть ли план восстановления и точные инструкции
  • прогнаны ли миграции в staging

Быстрый справочник и сниппеты

Подключение через URI:

const sequelize = new Sequelize(process.env.POSTGRESQL_DB_URI)

Запрос с сортировкой и лимитом:

const recentUsers = await User.findAll({
  where: { employed: true },
  order: [['createdAt', 'DESC']],
  limit: 10,
})

Транзакция:

const result = await sq.transaction(async t => {
  const a = await ModelA.create({ /*...*/ }, { transaction: t })
  const b = await ModelB.update({ /*...*/ }, { where: { id: a.id }, transaction: t })
  return { a, b }
})

Индексы и уникальные ограничения определяются в модели через параметры индексов или уникальные поля.

Рекомендации по тестированию и критериям приёмки

Критерии приёмки для базовой интеграции:

  • приложение устанавливает соединение с базой и authenticate() возвращает без ошибок
  • базовая модель создала таблицу и CRUD-операции работают в тестовой среде
  • миграции применяются и откатываются в тестовом окружении
  • мониторинг фиксирует количество подключений и ошибки

Тестовые кейсы:

  • создать, прочитать, обновить, удалить запись через API
  • проверить обработку ошибок при недоступности базы
  • протестировать откат транзакции при ошибке

План действий при инциденте и откате

Если миграция привела к потере данных или нарушению функционала:

  1. срочно переключить трафик на статическое резервное окружение или предыдущий релиз
  2. восстановить бэкап базы в тестовой среде и провести анализ
  3. откатить проблемную миграцию при помощи инструментов миграций
  4. ввести режим обслуживания при необходимости и уведомить заинтересованные стороны

Важно: заранее тестировать процедуры восстановления и отката на регулярной основе.

Частые ошибки и отладка

  • ошибка аутентификации: проверьте переменные окружения и сетевой доступ
  • конфликт версий pg и sequelize: сверяйте совместимость в changelog
  • потеря данных после sync({ force: true }): избегайте в проде, используйте бэкапы
  • медленные запросы: добавьте индексы, оптимизируйте запросы, профилируйте через pg_stat_statements

Заключение

Sequelize упрощает работу с PostgreSQL, позволяя работать на уровне моделей и методов без нужно писать SQL вручную. Для продакшна рекомендуются миграции, управление секретами, SSL-соединения и регулярные бэкапы. Если проект требует строгой типизации или высокой производительности, стоит сравнить Sequelize с альтернативами.

В этой статье были приведены примеры подключения, создания моделей и основных операций CRUD, а также дополнительные рекомендации по безопасности, разработке через Docker и обработке инцидентов.

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

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство