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