Миграции баз данных в Rust: обзор инструментов Diesel, SeaORM и sqlx

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

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

Начать курс

Миграции баз данных в Rust: обзор инструментов Diesel, SeaORM и sqlx

Управление изменениями схемы базы данных — одна из ключевых задач в разработке любого веб-приложения. В экосистеме Rust для этой цели существует несколько зрелых инструментов. В этой статье мы рассмотрим три основных подхода к миграциям: Diesel, SeaORM и sqlx. Каждый из них предлагает свой уникальный подход к управлению версиями схемы БД, и выбор правильного инструмента может существенно повлиять на архитектуру проекта.

1. Diesel — классический ORM с интеграцией миграций

Diesel — это безопасный, расширяемый ORM и Query Builder для Rust, который тесно интегрирован с системой миграций. Его главное преимущество — проверка типов на уровне компиляции: структуры таблиц генерируются на основе схемы БД, что исключает ошибки несоответствия типов.

Миграции в Diesel — это обычные SQL-файлы, организованные в директории migrations/. Каждая миграция содержит два файла: up.sql (применение изменений) и down.sql (откат).

Пример структуры миграции для создания таблицы пользователей:

-- migrations/2024-01-15-120000_create_users/up.sql
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(255) NOT NULL UNIQUE,
    email VARCHAR(255) NOT NULL UNIQUE,
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- migrations/2024-01-15-120000_create_users/down.sql
DROP TABLE IF EXISTS users;

Для запуска миграций используется CLI-инструмент diesel_cli:

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

# Запуск миграций
diesel migration run

# Откат последней миграции
diesel migration revert

# Генерация новой миграции
diesel migration generate create_users

Плюсы Diesel:

  • Полная проверка типов на этапе компиляции
  • Простая и понятная структура миграций (чистый SQL)
  • Встроенная поддержка откатов
  • Отличная производительность

Минусы:

  • Требуется установка дополнительного CLI-инструмента
  • Сложная настройка для проектов с несколькими базами данных
  • Меньшая гибкость по сравнению с sqlx

2. SeaORM — асинхронный ORM с гибкой системой миграций

SeaORM (на основе sea-query и sqlx) — это асинхронный ORM, который предлагает более современный подход к миграциям. В отличие от Diesel, миграции в SeaORM пишутся на Rust, а не на SQL, что позволяет использовать всю мощь языка для описания изменений схемы.

Пример миграции с использованием SeaORM:

use sea_orm_migration::prelude::*;

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        manager
            .create_table(
                Table::create()
                    .table(Users::Table)
                    .if_not_exists()
                    .col(
                        ColumnDef::new(Users::Id)
                            .integer()
                            .not_null()
                            .auto_increment()
                            .primary_key(),
                    )
                    .col(ColumnDef::new(Users::Username).string().not_null())
                    .col(ColumnDef::new(Users::Email).string().not_null())
                    .col(
                        ColumnDef::new(Users::CreatedAt)
                            .timestamp()
                            .default(Expr::current_timestamp()),
                    )
                    .to_owned(),
            )
            .await
    }

    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        manager
            .drop_table(Table::drop().table(Users::Table).to_owned())
            .await
    }
}

SeaORM предоставляет встроенную поддержку миграций через sea-orm-cli:

# Генерация новой миграции
sea-orm-cli migrate generate create_users_table

# Применение миграций
sea-orm-cli migrate up

# Откат
sea-orm-cli migrate down

Плюсы SeaORM:

  • Миграции на Rust — полный контроль и типизация
  • Асинхронность из коробки
  • Простая интеграция с Actix-web и Axum
  • Хорошая документация

Минусы:

  • Больше шаблонного кода по сравнению с SQL-миграциями
  • Менее зрелый, чем Diesel
  • Зависимость от

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