Diesel
01 / 02

Type-Safe Queries: Schema, Queryable & Insertable

Type-Safe Queries: Schema, Queryable & Insertable

Compile-Time-Checked SQL

Diesel is Rust's most widely used ORM/query builder, supporting PostgreSQL, MySQL, and SQLite. Its core value: table and column types are encoded in Rust's type system, so a query referencing a wrong column or mismatched type fails at compile time instead of surfacing as a runtime SQL error in production.

schema.rs — The Generated Source of Truth

// generated by `diesel print-schema` after running migrations
diesel::table! {
    users (id) {
        id -> Int4,
        email -> Varchar,
        created_at -> Timestamp,
    }
}

schema.rs mirrors the actual database structure and is what the query builder type-checks against. It's regenerated whenever migrations run, keeping application code in sync with the real schema rather than a hand-maintained model that can drift.

Queryable & Insertable Structs

#[derive(Queryable)]
struct User {
    id: i32,
    email: String,
    created_at: chrono::NaiveDateTime,
}

#[derive(Insertable)]
#[diesel(table_name = users)]
struct NewUser<'a> {
    email: &'a str,
}

Queryable deserializes a returned row into a struct, matching fields to selected columns by order. Insertable lets a struct be passed to .values() in an insert, mapping fields to target columns — both keep row↔struct conversion type-checked rather than manual.

Filtering & Loading

use self::schema::users::dsl::*;

let results = users
    .filter(email.eq("alice@example.com"))
    .order(created_at.desc())
    .limit(10)
    .load::<User>(&mut conn)?;

Queries are built via chained, typed methods (.filter, .eq, .order, .limit) that compose into SQL. A nonexistent column or type mismatch anywhere in the chain is a compile error, not something discovered when the query runs.

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free