Миграции баз данных в Rust: Обзор инструментов и библиотек

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

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

Начать курс

Миграции баз данных в Rust: Обзор инструментов и библиотек

При разработке любого приложения рано или поздно возникает необходимость изменить структуру базы данных. Добавление новых колонок, создание индексов или переименование таблиц — всё это требует аккуратного управления версиями схемы. В экосистеме Rust существует несколько зрелых решений для выполнения миграций. В этой статье мы рассмотрим основные подходы и библиотеки, доступные для задач управления схемой БД.

Зачем нужны миграции?

Миграции позволяют:

  • Версионировать изменения — каждая миграция представляет собой отдельный файл с номером версии.
  • Автоматизировать развёртывание — накатывать и откатывать изменения при деплое.
  • Работать в команде — все разработчики синхронизируют схему локально.
  • Избегать ошибок — миграции защищают от случайного изменения данных.

Основные инструменты для миграций в Rust

1. Diesel Migration (встроенный в Diesel ORM)

Diesel — самый популярный ORM для Rust. Он предоставляет встроенный движок для миграций через CLI-утилиту diesel_cli.

Основные возможности:

  • Генерация файлов миграций с SQL-запросами.
  • Поддержка PostgreSQL, MySQL, SQLite.
  • Команды: migration generate, migration run, migration redo.
  • Автоматическое отслеживание применённых миграций.

Пример создания и применения миграции:

# Установка CLI
cargo install diesel_cli --no-default-features --features postgres

# Создание новой миграции
diesel migration generate create_users

# В папке migrations/ появятся два SQL-файла:
# up.sql — код для наката
# down.sql — код для отката

# Применение миграции
diesel migration run

Содержимое up.sql:

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT NOW()
);

down.sql:

DROP TABLE IF EXISTS users;

2. SQLx migrate (часть экосистемы SQLx)

SQLx — асинхронный драйвер для SQL-баз данных. Его подсистема миграций работает без ORM, только с чистыми SQL-скриптами.

Отличительные черты:

  • Поддержка PostgreSQL, MySQL, SQLite, MSSQL.
  • Интеграция с CLI и программный запуск из кода.
  • Возможность использования Rust-кода для проверок перед миграцией.
  • Автоматическая проверка целостности (хеши файлов).

Пример программного запуска миграций в Rust:

use sqlx::migrate::Migrator;
use sqlx::PgPool;

#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = PgPool::connect("postgres://user:pass@localhost/db").await?;
    
    // Указываем путь к папке с миграциями
    let migrator = Migrator::new(std::path::Path::new("./migrations")).await?;
    
    // Запускаем все неприменённые миграции
    migrator.run(&pool).await?;
    
    println!("Миграции выполнены успешно!");
    Ok(())
}

Структура папки migrations/:

migrations/
├── 20231001_initial.sql
├── 20231002_add_email_index.sql
└── 20231003_create_roles.sql

Каждый файл содержит обычный SQL, например:

-- 20231001_initial.sql
CREATE TABLE IF NOT EXISTS users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    username TEXT NOT NULL UNIQUE
);

3. SeaORM Migrator (часть SeaORM)

SeaORM — современный асинхронный ORM, который предлагает собственную систему миграций SeaORM Migrator. Она позволяет писать миграции на Rust, а не на SQL, что даёт больше контроля и типобезопасность.

Преимущества:

  • Миграции пишутся на Rust с использованием структурированного API.
  • Поддержка PostgreSQL, MySQL, SQLite.
  • Встроенная поддержка откатов (rollback).
  • Генерация миграций через CLI.

Пример миграции на Rust:

use sea_orm_migration::prelude::*;                    

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