ORM لـ Rust: مقارنة مفصلة وأمثلة استخدام
يقدم نظام Rust البيئي عدة حلول قوية للعمل مع قواعد البيانات. في هذه المقالة، سنستعرض ثلاثة من أشهر ORMs (تعيين الكائنات العلائقية) لـ Rust: Diesel، SeaORM و SQLx. لكل منها نقاط قوته الخاصة ويناسب سيناريوهات مختلفة. سنقارنها حسب الخصائص الرئيسية ونقدم أمثلة عملية على الكود.
1. Diesel — ORM كلاسيكي بأقصى أداء
Diesel هو أكثر ORM نضجًا في نظام Rust البيئي. يعمل بشكل متزامن (مع دعم التزامن غير المتزامن عبر diesel-async) ويشتهر بأدائه العالي وأمان أنواعه.
الميزات الرئيسية:
- أمان تام للأنواع: يتم اكتشاف أخطاء SQL في مرحلة الترجمة
- دعم PostgreSQL، MySQL، SQLite
- توليد المخطط عبر أداة CLI
diesel_cli - محسّن للاستعلامات المعقدة والمعاملات
مثال كود مع Diesel:
// تعريف النموذج#[derive(Queryable, Insertable)]#[diesel(table_name = crate::schema::users)]struct User { id: i32, name: String, email: String,}
// إضافة مستخدم جديدfn create_user(conn: &mut PgConnection, name: &str, email: &str) -> User { let new_user = NewUser { name, email }; diesel::insert_into(users::table) .values(&new_user) .get_result(conn) .expect("خطأ في حفظ المستخدم الجديد")}
// استعلام جميع المستخدمينfn get_all_users(conn: &mut PgConnection) -> Vec<User> { users::table .load::<User>(conn) .expect("خطأ في تحميل المستخدمين")}2. SeaORM — ORM غير متزامن بنموذج نشط
SeaORM هو ORM حديث غير متزامن، مستوحى من Entity Framework و Active Record. يوفر واجهة برمجة تطبيقات مريحة لبناء الاستعلامات ويدعم الترحيلات "خارج الصندوق".
الميزات الرئيسية:
- غير متزامن افتراضيًا (بناءً على Tokio)
- نموذج نشط: يمكن استدعاء دوال على الكيانات
- دعم العلاقات (has_many، belongs_to، many_to_many)
- ترحيلات مدمجة وأداة CLI
مثال كود مع SeaORM:
use sea_orm::{entity::prelude::*, Database, EntityTrait};
// تعريف الكيان#[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 run() { let db = Database::connect("postgres://user:pass@localhost/db").await.unwrap(); // إدراج let user = ActiveModel { name: Set("Alice".to_owned()), email: Set("alice@example.com".to_owned()), ..Default::default() }; let result = Entity::insert(user).exec(&db).await.unwrap(); // جلب الكل let users: Vec<Model> = Entity::find().all(&db).await.unwrap();}3. SQLx — ليس ORM، بل مشغل SQL غير متزامن مع التحقق في مرحلة الترجمة
SQLx يحتل موقعًا وسيطًا: ليس ORM كاملًا، لكنه يوفر أدوات قوية للعمل مع SQL مع التحقق من الاستعلامات أثناء الترجمة. إنه مثالي لمن يفضلون كتابة SQL نقي ولكنهم يريدون تجنب الأخطاء.
الميزات الرئيسية:
- غير متزامن (Tokio، async-std)
- التحقق من استعلامات SQL في مرحلة الترجمة عبر الماكرو
sqlx::query! - دعم PostgreSQL، MySQL، SQLite، MSSQL
- خفيف الوزن، بدون سحر ORM