Миграции баз данных в JavaScript (Node.js): Инструменты и практика
Разработка современных веб-приложений на Node.js редко обходится без работы с базами данных. По мере роста проекта структура таблиц, индексы и связи неизбежно меняются. Ручное выполнение SQL-скриптов на сервере — путь к хаосу и ошибкам. Решение этой проблемы — миграции баз данных (database migrations). Это механизм версионирования изменений схемы, позволяющий команде разработчиков синхронно и безопасно обновлять структуру БД.
В экосистеме JavaScript существует несколько зрелых инструментов для работы с миграциями. Рассмотрим три ключевых подхода на примере популярных библиотек.
1. Knex.js — универсальный конструктор запросов
Knex.js — это не просто SQL-билдер, но и полноценный инструмент для миграций и сидинга (наполнения тестовыми данными). Он поддерживает PostgreSQL, MySQL, SQLite и другие СУБД. Главное преимущество — вы пишете миграции на JavaScript, а Knex транслирует их в диалект конкретной базы.
Установка и настройка
npm install knex
npm install pg # для PostgreSQL
Создаём файл конфигурации knexfile.js:
module.exports = {
development: {
client: 'pg',
connection: {
host: 'localhost',
user: 'user',
password: 'pass',
database: 'mydb'
},
migrations: {
directory: './migrations'
}
}
};
Создание и выполнение миграции
Создадим миграцию для таблицы пользователей:
npx knex migrate:make create_users_table
В папке migrations появится файл с меткой времени. Редактируем его:
exports.up = function(knex) {
return knex.schema.createTable('users', (table) => {
table.increments('id').primary();
table.string('username', 100).notNullable().unique();
table.string('email').notNullable();
table.timestamps(true, true); // created_at и updated_at
});
};
exports.down = function(knex) {
return knex.schema.dropTableIfExists('users');
};
Применяем миграцию:
npx knex migrate:latest
Откат последней миграции:
npx knex migrate:rollback
Knex также позволяет выполнять чистый SQL внутри миграций, если требуется специфичная логика.
2. Sequelize — ORM с мощной системой миграций
Sequelize — популярный ORM для Node.js, поддерживающий PostgreSQL, MySQL, MariaDB, SQLite и MSSQL. Его CLI предоставляет удобные команды для генерации и управления миграциями, плотно интегрированными с моделями.
Начало работы
npm install sequelize sequelize-cli pg
npx sequelize-cli init
Создаём модель и миграцию одной командой:
npx sequelize-cli model:generate --name User --attributes username:string,email:string
Это сгенерирует два файла: модель models/user.js и миграцию в migrations/. Пример миграции:
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('Users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
username: {
type: Sequelize.STRING(100),
allowNull: false,
unique: true
},
email: {
type: Sequelize.STRING,
allowNull: false
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('Users');
}
};
Применение и откат:
npx sequelize-cli db:migrate
npx sequelize-cli db:migrate:undo
3. TypeORM — миграции для TypeScript и JavaScript
TypeORM — ORM, который работает как с TypeScript, так и с чистым JavaScript. Его система миграций автоматически генерирует SQL на основе изменений в сущностях (entity), что минимизирует ручной код.
Генерация миграции из сущности
Предположим, у нас есть сущность User:
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({ length: 100, unique: true })
username: string