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

PostgreSQL с Sequelize в Node.js: полное руководство

6 min read Базы данных Обновлено 31 Dec 2025
PostgreSQL с Sequelize в Node.js — руководство
PostgreSQL с Sequelize в Node.js — руководство

Слон в лесу

  • Коротко: используйте Sequelize как ORM для удобной работы с PostgreSQL в приложениях Node.js. Установите PostgreSQL (локально или в облаке), добавьте пакеты sequelize и pg, настройте соединение через config/db.js, создайте модели и выполняйте запросы через методы модели (create, findAll, update, destroy). Для продакшна применяйте миграции, SSL, пул соединений и ограниченные права пользователя.
  • Когда это работает лучше всего: веб-приложения и API, где нужна структура данных, валидация и связи между таблицами.

Введение

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

Определения в одну фразу

  • ORM: библиотека для работы с БД через объекты вместо чистого SQL.
  • Модель: объект, описывающий таблицу и её колонки.
  • Синхронизация (sync): приведение схемы БД в соответствие с моделями.

Важно

Если вы храните персональные данные — продумайте шифрование, управление доступом и политику хранения в соответствии с локальными требованиями (например, GDPR).

Содержание

  • Требования и варианты установки PostgreSQL
  • Установка зависимостей npm
  • Конфигурация соединения (config/db.js)
  • Создание моделей и синхронизация
  • CRUD: создание, чтение, обновление, удаление
  • Ассоциации, транзакции, производительность
  • Безопасность и эксплуатация
  • Миграции, резервное копирование и развертывание
  • Чеклисты для ролей
  • Частые вопросы

Требования и варианты установки PostgreSQL

Локально:

  • Windows/macOS/Linux: скачайте инсталлятор с https://www.postgresql.org и следуйте инструкциям для вашей ОС.
  • macOS: можно установить через Homebrew: brew install postgresql.

В облаке:

  • ElephantSQL, Heroku Postgres, Amazon RDS, DigitalOcean Managed Databases и т.д. предлагают PostgreSQL как сервис.
  • Облачные провайдеры обычно предоставляют строку подключения (URI) и опции SSL.

Контейнеры:

  • Для разработки удобно использовать Docker Compose с официальным образом postgres.

Совет

Для разработки используйте отдельную базу данных и учётную запись с минимальными привилегиями.

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

Инициализируйте проект (если ещё не):

npm init -y

Установите Sequelize и драйвер PostgreSQL:

npm install sequelize
npm install pg pg-hstore

Дополнительно (рекомендуется):

  • sequelize-cli или umzug для миграций и сидеров
  • dotenv для управления переменными окружения
npm install sequelize-cli dotenv

Шаг 2: Конфигурация соединения (config/db.js)

Создайте папку config и файл config/db.js. Используйте переменные окружения для секретов.

Пример config/db.js:

// config/db.js
const { Sequelize } = require("sequelize");
require('dotenv').config();

// Используем переменную окружения POSTGRESQL_DB_URI если доступна
const connectionUri = process.env.POSTGRESQL_DB_URI || null;

const sequelize = connectionUri
  ? new Sequelize(connectionUri, {
      dialect: 'postgres',
      logging: false, // включите для отладки
      pool: {
        max: 10,
        min: 0,
        acquire: 30000,
        idle: 10000,
      },
      dialectOptions: process.env.DB_SSL === 'true' ? { ssl: { rejectUnauthorized: false } } : {},
    })
  : new Sequelize(process.env.POSTGRES_DB || 'database', process.env.POSTGRES_USER || 'username', process.env.POSTGRES_PASSWORD || 'password', {
      host: process.env.POSTGRES_HOST || 'localhost',
      port: process.env.POSTGRES_PORT ? Number(process.env.POSTGRES_PORT) : 5432,
      dialect: 'postgres',
      logging: false,
      pool: {
        max: 10,
        min: 0,
        acquire: 30000,
        idle: 10000,
      },
    });

const testDbConnection = async () => {
  try {
    await sequelize.authenticate();
    console.log('Connection has been established successfully.');
  } catch (error) {
    console.error('Unable to connect to the database:', error);
    throw error;
  }
};

module.exports = { sq: sequelize, testDbConnection };

Пояснения:

  • Рекомендуется хранить строку подключения в переменных окружения (POSTGRESQL_DB_URI) или использовать менеджер секретов.
  • Параметры pool управляют пулом соединений.
  • dialectOptions.ssl включайте если провайдер требует SSL.

Критерии приёмки (подключение):

  • Тест подключения успешно проходит (testDbConnection не выбрасывает ошибку).
  • В продакшне используются переменные окружения и SSL при необходимости.

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

Создайте папку models. Пример модели User в models/user.js:

// models/user.js
const { sq } = require('../config/db');
const { DataTypes } = require('sequelize');

const User = sq.define('User', {
  id: {
    type: DataTypes.UUID,
    defaultValue: DataTypes.UUIDV4,
    primaryKey: true,
  },
  email: {
    type: DataTypes.STRING,
    allowNull: false,
    unique: true,
    validate: {
      isEmail: true,
    },
  },
  fullName: {
    type: DataTypes.STRING,
    allowNull: true,
  },
  age: {
    type: DataTypes.INTEGER,
    allowNull: true,
  },
  employed: {
    type: DataTypes.BOOLEAN,
    defaultValue: false,
  },
}, {
  tableName: 'users',
  timestamps: true,
  paranoid: true, // включить мягкое удаление
});

module.exports = User;

Пояснения:

  • Используйте UUID для уникальных идентификаторов, если это применимо.
  • Включите уникальные индексы (unique) на полях, где требуется.
  • paranoid: true включает мягкое удаление (deletedAt вместо полного удаления).

Синхронизация моделей (sync) — осторожно в продакшне

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

Рекомендация: в продакшне используйте миграции (sequelize-cli или umzug), а не sync({ force: true }) или alter в автоматическом режиме.

Основные операции (CRUD)

Сохранение записи (Create):

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

Получение записей (Read):

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

// Один пользователь
const someUser = await User.findOne({ where: { email: 'mike@example.com' } });

// С фильтром
const unemployed = await User.findAll({ where: { employed: false } });

// С пагинацией
const page = 1;
const pageSize = 20;
const pageUsers = await User.findAll({ limit: pageSize, offset: (page - 1) * pageSize });

Полезно: операторы (Op)

const { Op } = require('sequelize');
const adults = await User.findAll({ where: { age: { [Op.gte]: 18 } } });

Обновление записей (Update):

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

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

Удаление записей (Delete):

// Полное удаление
await User.destroy({ where: { email: 'mike@example.org' } });

// Если paranoid: true — удаление будет мягким (deletedAt)

Транзакции

await sq.transaction(async (t) => {
  const newUser = await User.create({ email: 'tx@example.com' }, { transaction: t });
  // другие операции в той же транзакции
});

Транзакции важны для целостности данных при нескольких зависимых операциях.

Ассоциации (отношения между моделями)

Sequelize поддерживает: hasOne, belongsTo, hasMany, belongsToMany.

Пример: User и Post

// models/post.js
const { sq } = require('../config/db');
const { DataTypes } = require('sequelize');
const Post = sq.define('Post', {
  id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true },
  title: { type: DataTypes.STRING },
  content: { type: DataTypes.TEXT },
});
module.exports = Post;

// в точке инициализации моделей
const User = require('./user');
const Post = require('./post');
User.hasMany(Post, { foreignKey: 'userId' });
Post.belongsTo(User, { foreignKey: 'userId' });

Запрос с подгрузкой (eager loading):

const posts = await Post.findAll({ include: [{ model: User }] });

Миграции и управление схемой

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

Пример команды с sequelize-cli (установлен глобально или в package.json):

npx sequelize-cli migration:generate --name add-users-table
npx sequelize-cli db:migrate

Производительность и оптимизация

  1. Индексы: создавайте индексы на полях, используемых в where и join.
  2. Запрашивайте только нужные колонки через attributes.
  3. Пагинация с limit/offset или cursor-based для больших наборов.
  4. Используйте пул соединений и настройте max/min в зависимости от нагрузки.
  5. Для тяжёлых запросов используйте сырой SQL: sq.query(‘SELECT …’)

Безопасность и эксплуатация

  • Не храните пароли в репозитории — используйте переменные окружения или секреты.
  • Дайте пользовательскому аккаунту БД минимально необходимые права.
  • Включите SSL при подключении к облачным БД.
  • Логируйте ошибки, но не выводите секреты в лог.

Резервное копирование и стратегия отката

  • Регулярно создавайте бэкапы (слепки) и тестируйте восстановление.
  • Для миграций поддерживайте скрипты отката.

Когда комбинация Sequelize + PostgreSQL может не подойти

  • Если вам нужен максимально тонкий контроль SQL и производительность на уровне тонких оптимизаций — чистый SQL или легковесный query builder (Knex) может быть предпочтительнее.
  • Для аналитических запросов с большими агрегатами иногда проще писать оптимизированные SQL-запросы.

Альтернативы

  • TypeORM — более «TypeScript-ориентированная» ORM.
  • Objection.js + Knex — гибрид ORM/query builder.
  • Prisma — современный ORM с хорошей разработкой типов (поддержка PostgreSQL).

Практические советы для деплоя

  • В prod: используйте миграции, отключите автоматический sync на старте.
  • Настройте health checks: периодически вызывайте тест соединения.
  • Ограничьте количество одновременно открытых соединений согласно возможностям БД.

Чеклисты

Чеклист для разработчика:

  • Проект содержит .env.example с нужными переменными (POSTGRESQL_DB_URI, DB_SSL и т.д.)
  • Модели находятся в папке models, экспортированы корректно
  • Используются миграции вместо sync в prod
  • Тесты покрывают основные CRUD операции

Чеклист для DevOps/инженера по релизам:

  • Бэкап БД перед миграциями
  • Проверка наличия SSL и пулов
  • Мониторинг соединений и задержек

Чеклист для DBA:

  • Индексы покрывают частые запросы
  • Планы запросов проверены для тяжёлых выборок
  • Настроены ротация журналов и бэкапы

Шаблон конфигурации .env.example

# .env.example
POSTGRESQL_DB_URI=postgres://user:pass@host:5432/dbname
DB_SSL=true
POSTGRES_DB=app_db
POSTGRES_USER=app_user
POSTGRES_PASSWORD=secret
POSTGRES_HOST=localhost
POSTGRES_PORT=5432

Decision flow: sync vs миграции (Mermaid)

flowchart TD
  A[Начало разработки] --> B{Развертывание в прод}
  B -- Нет --> C[Можно использовать sync'' для быстроты]
  B -- Да --> D[Использовать миграции 'sequelize-cli / umzug']
  C --> E[Тестирование локально]
  D --> F[Создать и применить миграции, сделать бэкап]
  E --> G[Подготовка к деплою]
  F --> G

Фрагменты кода — шпаргалка (cheat sheet)

Подключение модулей:

const { sq, testDbConnection } = require('./config/db');
const User = require('./models/user');

Пул соединений и логирование:

const sequelize = new Sequelize(uri, {
  pool: { max: 20, min: 2, idle: 10000 },
  logging: (msg) => console.debug(msg),
});

Транзакция с try/catch:

const t = await sq.transaction();
try {
  const u = await User.create({ email: 't@example.com' }, { transaction: t });
  await t.commit();
} catch (err) {
  await t.rollback();
  throw err;
}

Локальные альтернативы и подводные камни

  • Если вы планируете сложные миграции с переименованиями колонок и долгими откатами, тестируйте сценарии миграций на копии БД.
  • При использовании облачных провайдеров внимательно проверьте ограничения на количество подключений.

Безопасность данных и GDPR (коротко)

  • Храните минимум персональных данных и срок их хранения.
  • Контролируйте доступ по ролям и журналируйте действия администраторов.
  • При переносе данных используйте защищённые каналы и проверьте требования локального законодательства.

Часто задаваемые вопросы (FAQ)

Как безопасно хранить строку подключения?

Храните её в переменных окружения или в менеджере секретов (AWS Secrets Manager, HashiCorp Vault) и не коммитьте в репозиторий.

Можно ли использовать sync() в продакшне?

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

Что делать, если соединение падает под нагрузкой?

Проверьте настройки пула, max_connections на стороне PostgreSQL и используйте connection pooling в приложении.

Как сделать откат миграции?

Создавайте обратимые миграции и тестируйте командой db:migrate:undo или используйте инструменты миграций, поддерживающие откат.

Ресурсы и дальнейшее чтение

  • Официальная документация Sequelize: https://sequelize.org
  • Официальная документация PostgreSQL: https://www.postgresql.org
  • ElephantSQL и другие провайдеры: провайдерская документация по подключению

Короткое заключение

Sequelize + PostgreSQL — надёжное сочетание для большинства веб-приложений. Следуйте лучшим практикам: миграции, безопасность, пул соединений и контроль доступа. Начните с простых моделей, добавляйте ассоциации и транзакции по мере роста приложения.

Important

  • Всегда тестируйте миграции и бэкапы на неглавной среде перед применением в продакшне.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

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

iPhone не включается: что делать
Гаджеты

iPhone не включается: что делать

Запись эфирного ТВ на ПК с NextPVR
How-to

Запись эфирного ТВ на ПК с NextPVR

Google Формы: как создать форму и собрать данные
Руководство

Google Формы: как создать форму и собрать данные

Разблокировать загрузчик Android — безопасный гид
Android.

Разблокировать загрузчик Android — безопасный гид

Утечка данных Equifax — как проверить и что делать
Кибербезопасность

Утечка данных Equifax — как проверить и что делать

Как освободить место на iPhone
Мобильные устройства

Как освободить место на iPhone