Миграции баз данных в Node.js: Sequelize, Knex и TypeORM

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Миграции баз данных в JavaScript (Node.js): полный обзор инструментов

Миграции баз данных — это способ контролируемого и версионированного изменения схемы базы данных. В мире Node.js существует несколько мощных библиотек, которые позволяют автоматизировать этот процесс. В этой статье мы рассмотрим три самых популярных инструмента: Sequelize, Knex.js и TypeORM.

Что такое миграции и зачем они нужны?

Миграции решают проблему синхронизации структуры базы данных между разработчиками и окружениями (dev, staging, production). Вместо того чтобы вручную выполнять SQL-скрипты, вы описываете изменения в коде на JavaScript/TypeScript. Преимущества:

  • Автоматическое применение изменений
  • Возможность отката (rollback) до предыдущей версии
  • Хранение истории изменений в репозитории
  • Поддержка разных СУБД (PostgreSQL, MySQL, SQLite и др.)

1. Sequelize — ORM с встроенной системой миграций

Sequelize — один из самых популярных ORM для Node.js. Он предоставляет CLI-инструмент для управления миграциями. Установка:

npm install --save sequelize
npm install --save-dev sequelize-cli
npx sequelize-cli init

После инициализации создаются папки migrations, models, seeders и файл конфигурации config/config.json.

Создание миграции

npx sequelize-cli migration:generate --name create-users-table

Пример содержимого миграции:

'use strict';
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable('Users', {
      id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
      },
      username: {
        type: Sequelize.STRING,
        allowNull: false,
        unique: true
      },
      email: {
        type: Sequelize.STRING,
        allowNull: false
      },
      createdAt: {
        type: Sequelize.DATE,
        allowNull: false
      },
      updatedAt: {
        type: Sequelize.DATE,
        allowNull: false
      }
    });
  },
  down: async (queryInterface, Sequelize) => {
    await queryInterface.dropTable('Users');
  }
};

Применение и откат

npx sequelize-cli db:migrate
npx sequelize-cli db:migrate:undo

2. Knex.js — SQL query builder с миграциями

Knex.js — это не ORM, а мощный построитель запросов. Его система миграций считается одной из самых гибких. Установка:

npm install knex --save
npm install pg --save  # или mysql, sqlite3
npx knex init

Создание и написание миграции

npx knex migrate:make create_posts_table

Пример кода:

exports.up = function(knex) {
  return knex.schema.createTable('posts', (table) => {
    table.increments('id').primary();
    table.string('title', 255).notNullable();
    table.text('content');
    table.integer('user_id').unsigned().references('id').inTable('users');
    table.timestamps(true, true);
  });
};

exports.down = function(knex) {
  return knex.schema.dropTableIfExists('posts');
};

Команды для работы

npx knex migrate:latest
npx knex migrate:rollback
npx knex migrate:status  # просмотр статуса

Knex также поддерживает «семена» (seeds) для начального заполнения данными:

npx knex seed:make 01_demo_users
npx knex seed:run

3. TypeORM — миграции для TypeScript проектов

TypeORM — современный ORM, который поддерживает как JavaScript, так и TypeScript. Его система миграций тесно интегрирована с декораторами сущностей. Установка:

npm install typeorm reflect-metadata --save
npm install @types/node --save-dev
npx typeorm init

Генерация миграции из сущностей

TypeORM умеет автоматически создавать миграцию на основе изменений в ваших сущностях (Entity):

npx typeorm migration:generate -n CreateUserEntity

Пример сгенерированного файла:

import {MigrationInterface, QueryRunner, Table} from "typeorm";

export class CreateUserEntity1234567890 implements MigrationInterface {
    public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.createTable(new Table({
            name: "user",
            columns: [
                { name: "id", type: "int", isPrimary                    

Рекомендаций