ORM для Rust: сравнение и примеры Diesel, SeaORM, SQLx

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

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

Начать курс

ORM для Rust: полное сравнение и примеры использования

Экосистема Rust предлагает несколько мощных решений для работы с базами данных. В этой статье мы подробно сравним три основных подхода: Diesel (синхронный, компилируемый ORM), SeaORM (асинхронный, гибкий) и SQLx (минималистичный, с проверкой запросов на этапе компиляции). Вы узнаете, какой инструмент выбрать под конкретные задачи, и увидите рабочие примеры кода.

1. Diesel — проверенный синхронный ORM

Diesel — это самый зрелый ORM для Rust. Его главная фишка — безопасность типов на этапе компиляции. Все SQL-запросы проверяются во время сборки, что исключает целый класс ошибок. Работает только синхронно, но с tokio можно организовать пул соединений.

Пример использования Diesel:

// models.rs
#[derive(Queryable, Insertable)]
#[table_name = "users"]
pub struct User {
    pub id: i32,
    pub name: String,
    pub email: String,
}

// main.rs
use diesel::prelude::*;
use diesel::dsl::insert_into;

fn main() {
    let conn = PgConnection::establish("postgres://user:pass@localhost/db")
        .expect("Database connection failed");

    let new_user = User {
        id: 0,
        name: "Alice".into(),
        email: "alice@example.com".into(),
    };

    let inserted = insert_into(users::table)
        .values(&new_user)
        .get_result::<User>(&conn)
        .expect("Insert failed");

    println!("Created user: {}", inserted.name);
}

Плюсы: максимальная производительность, строгая типизация, встроенные миграции.

Минусы: синхронный, сложная настройка, не поддерживает async из коробки.

2. SeaORM — асинхронный и гибкий

SeaORM — это современный асинхронный ORM, построенный на sqlx. Поддерживает tokio и async-std. Предлагает богатый API для CRUD, отношений (один-к-одному, один-ко-многим) и миграций. Идеален для веб-приложений на Actix или Axum.

Пример с SeaORM:

use sea_orm::*;
use sea_orm::entity::prelude::*;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "users")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    pub name: String,
    pub email: String,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}

impl ActiveModelBehavior for ActiveModel {}

// Использование
async fn create_user(db: &DatabaseConnection) -> Result<(), DbErr> {
    let user = ActiveModel {
        name: Set("Bob".to_owned()),
        email: Set("bob@example.com".to_owned()),
        ..Default::default()
    };
    let result = user.insert(db).await?;
    println!("User created with id: {}", result.id);
    Ok(())
}

Плюсы: полноценный async, поддержка PostgreSQL, MySQL, SQLite, простые миграции.

Минусы: медленнее Diesel на синтетических тестах, больше зависимостей.

3. SQLx — легковесный и безопасный

SQLx — это не ORM в классическом смысле, а асинхронный SQL-драйвер с проверкой запросов на этапе компиляции. Вы пишете чистый SQL, а SQLx проверяет его синтаксис и типы аргументов. Поддерживает PostgreSQL, MySQL, SQLite. Отличный выбор, если вы предпочитаете полный контроль над запросами.

Пример SQLx:

use sqlx::postgres::PgPool;

#[derive(sqlx::FromRow)]
struct User {
    id: i32,
    name: String,
    email: String,
}

#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
    let pool = PgPool::connect("postgres://user:pass@localhost/db").await?;

    let user = sqlx::query_as::<_, User>(
        "SELECT id, name, email FROM users WHERE email = $1"
    )
    .bind("charlie@example.com")
    .fetch_one(&pool)
    .await?;

    println!("Found user: {}", user.name);
    Ok(())
}

Плюсы: минимальный overhead, проверка SQL в compile time, async, поддержка миграций.

Минусы: нет автоматической генерации запросов, нужно писать SQL вручную.

4. Сравнительная таблица

  • Diesel: Синхронный, строгая типизация, максимальная скорость. Для консольных утилит и высоконагружен

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