--- name: Diesel ORM description: Type-safe Rust ORM with compile-time query validation. metadata: labels: [rust, diesel, orm, database, postgresql] triggers: files: ['**/schema.rs', 'diesel.toml'] keywords: [diesel, Queryable, Insertable, table] --- # Diesel ORM Standards ## Schema Definition ```rust // Generated by diesel migration run // src/schema.rs diesel::table! { users (id) { id -> Int4, name -> Varchar, email -> Varchar, created_at -> Timestamp, } } ``` ## Model Structs ```rust use diesel::prelude::*; use crate::schema::users; #[derive(Queryable, Selectable, Debug)] #[diesel(table_name = users)] pub struct User { pub id: i32, pub name: String, pub email: String, pub created_at: NaiveDateTime, } #[derive(Insertable)] #[diesel(table_name = users)] pub struct NewUser<'a> { pub name: &'a str, pub email: &'a str, } #[derive(AsChangeset)] #[diesel(table_name = users)] pub struct UpdateUser<'a> { pub name: Option<&'a str>, pub email: Option<&'a str>, } ``` ## Connection Pool ```rust use diesel::pg::PgConnection; use diesel::r2d2::{Pool, ConnectionManager}; type DbPool = Pool>; fn establish_pool(database_url: &str) -> DbPool { let manager = ConnectionManager::::new(database_url); Pool::builder() .max_size(15) .build(manager) .expect("Failed to create pool") } ``` ## CRUD Operations ```rust use diesel::prelude::*; use crate::schema::users::dsl::*; // Create fn create_user(conn: &mut PgConnection, new_user: &NewUser) -> QueryResult { diesel::insert_into(users) .values(new_user) .get_result(conn) } // Read fn find_user(conn: &mut PgConnection, user_id: i32) -> QueryResult { users.find(user_id).first(conn) } fn list_users(conn: &mut PgConnection) -> QueryResult> { users.load(conn) } // Update fn update_user(conn: &mut PgConnection, user_id: i32, changes: &UpdateUser) -> QueryResult { diesel::update(users.find(user_id)) .set(changes) .get_result(conn) } // Delete fn delete_user(conn: &mut PgConnection, user_id: i32) -> QueryResult { diesel::delete(users.find(user_id)).execute(conn) } ``` ## Query Building ```rust // Filtering let active_users = users .filter(active.eq(true)) .filter(created_at.gt(cutoff_date)) .load::(conn)?; // Ordering and pagination let page = users .order(created_at.desc()) .limit(10) .offset(20) .load::(conn)?; // Select specific columns let emails: Vec = users .select(email) .load(conn)?; // Joins let user_posts = users .inner_join(posts::table) .select((users::name, posts::title)) .load::<(String, String)>(conn)?; ``` ## Transactions ```rust conn.transaction(|conn| { diesel::insert_into(users) .values(&new_user) .execute(conn)?; diesel::insert_into(audit_log) .values(&log_entry) .execute(conn)?; Ok(()) }) ``` ## Migrations ```bash # Create migration diesel migration generate create_users # Run pending migrations diesel migration run # Revert last migration diesel migration revert # Redo last migration diesel migration redo ``` ## Best Practices 1. **Schema sync**: Run `diesel migration run` before compile 2. **Pool sizing**: Match to expected concurrent connections 3. **Derive macros**: Use `Queryable` for reads, `Insertable` for writes 4. **Nullable**: Use `Option` for nullable columns 5. **Raw SQL**: Use `sql_query()` for complex queries when needed