ORM لـ Rust: مقارنة وأمثلة
يقدم نظام Rust البيئي العديد من الحلول القوية للعمل مع قواعد البيانات. في هذه المقالة، سنقارن بين ثلاث أدوات شائعة تشبه ORM: Diesel وSeaORM وSQLx. لكل منها فلسفته الخاصة ومجال استخدامه. سنستعرض ميزاتها وأداءها ونقدم أمثلة عملية.
1. Diesel — ORM كلاسيكي مع أمان الأنواع
Diesel هو أقدم ORM لـ Rust، مبني على مبدأ "أمان الأنواع أثناء التجميع". يتطلب وصفًا صريحًا للمخطط من خلال الترحيلات ويولد هياكل مطبقة بشكل صارم.
الميزات:
- يتحقق التجميع من صحة الاستعلامات (أخطاء SQL في مرحلة البناء)
- دعم PostgreSQL وMySQL وSQLite
- محرك متزامن (للتزامن، يتطلب
diesel-async) - لغة خاصة بالمجال (DSL) لبناء الاستعلامات
مثال برمجي (Diesel + PostgreSQL):
// models.rsuse diesel::prelude::*;
#[derive(Queryable, Selectable)]#[diesel(table_name = crate::schema::users)]#[diesel(check_for_backend(diesel::pg::Pg))]pub struct User { pub id: i32, pub name: String, pub email: String,}
// main.rsuse diesel::prelude::*;use diesel::pg::PgConnection;
fn get_user(conn: &mut PgConnection, user_id: i32) -> Option<User> { use crate::schema::users::dsl::*; users.filter(id.eq(user_id)) .first::<User>(conn) .ok()}متى تختاره: للمشاريع التي تكون فيها سلامة الاستعلامات في مرحلة التجميع أمرًا بالغ الأهمية، وكنت مستعدًا لمخطط صارم.
2. SeaORM — ORM غير متزامن مع نهج ActiveRecord
SeaORM هو ORM غير متزامن حديث، مستوحى من Ruby on Rails. يدعم كل من الكود أولاً وتوليد الكيانات من قاعدة بيانات موجودة.
الميزات:
- تزامن كامل (Tokio, async-std)
- دعم PostgreSQL وMySQL وSQLite وCockroachDB
- ترحيلات، علاقات (has_many, belongs_to)، ترقيم الصفحات
- مولد الكود
sea-orm-cli
مثال برمجي (SeaORM + PostgreSQL):
use sea_orm::*;use entity::user;
async fn find_user(db: &DatabaseConnection, user_id: i32) -> Result<Option<user::Model>, DbErr> { user::Entity::find_by_id(user_id) .one(db) .await}
// الاستخدامasync fn example() { let db = Database::connect("postgres://user:pass@localhost/db").await.unwrap(); if let Some(user) = find_user(&db, 42).await.unwrap() { println!("المستخدم: {} ({})", user.name, user.email); }}متى تختاره: لتطبيقات الويب غير المتزامنة (Actix, Axum) التي تحتاج إلى تطوير نشط ووظائف غنية "جاهزة للاستخدام".
3. SQLx — "تقريبًا ORM" بأقصى مرونة
SQLx ليس ORM بالكامل، بل هو عميل SQL غير متزامن مع التحقق من الاستعلامات. يسمح بكتابة SQL نقي، ولكنه يتحقق من صحته في مرحلة التجميع.
الميزات:
- التحقق من الاستعلامات أثناء التجميع (عبر الماكرو
sqlx::query!) - تزامن كامل
- دعم PostgreSQL وMySQL وSQLite وMSSQL
- دعم JSON والترحيلات وتجمع الاتصالات
مثال برمجي (SQLx + PostgreSQL):
use sqlx::PgPool;
#[derive(sqlx::FromRow)]struct User { id: i32, name: String, email: String,}
async fn get_user(pool: &PgPool, user_id: i32) -> Result<Option<User>, sqlx::Error> { sqlx::query_as::<_, User>("SELECT id, name, email FROM users WHERE id = $1") .bind(user_id) .fetch_optional(pool) .await}متى تختاره: إذا كنت تفضل كتابة SQL