Diesel is a Safe, Extensible
ORM and Query Builder
Diesel gets rid of the boilerplate for database interaction without sacrificing performance. It’s the most productive way to interact with databases in Rust.
Preventing Runtime Errors
Diesel eliminates the possibility of having a mismatch between your database schema and your Rust code. If it compiles, it’s valid. No more runtime surprises or production crashes due to typoed columns.
Built for Performance
Diesel is designed to be as fast as possible. It avoids heap allocations and runtime overhead where other ORMs might struggle. Zero-cost abstractions mean you pay for what you use.
Extensible Querying
Need a custom SQL function? Diesel’s query builder is fully extensible. You can define your own operators or use complex SQL features while maintaining type safety.
Productive Workflow
With integrated migrations, CLI tools, and automatic schema generation, Diesel streamlines your entire development lifecycle from the first table to production.
See it in action
Compare how Diesel transforms complex SQL into readable, safe Rust code.
Simple Queries
Simple queries are a complete breeze. Loading all users from a database:
users::table.load(&mut connection)
SELECT * FROM users;
Loading all the posts for a user:
Post::belonging_to(user).load(&mut connection)
SELECT * FROM posts WHERE user_id = 1;
Complex Queries
Diesel’s powerful query builder helps you construct queries as simple or complex as you need, at zero cost.
let versions = Version::belonging_to(krate)
.select(id)
.order(num.desc())
.limit(5);
let downloads = version_downloads
.filter(date.gt(now - 90.days()))
.filter(version_id.eq(any(versions)))
.order(date)
.load::<Download>(&mut conn)?;
SELECT version_downloads.*
WHERE date > (NOW() - '90 days')
AND version_id = ANY(
SELECT id FROM versions
WHERE crate_id = 1
ORDER BY num DESC
LIMIT 5
)
ORDER BY date
Less Boilerplate
Diesel codegen generates boilerplate for you. It lets you focus on your business logic, not mapping to and from SQL rows.
With Diesel:
#[derive(Queryable)]
pub struct Download {
id: i32,
version_id: i32,
downloads: i32,
counted: i32,
date: SystemTime,
}
Without Diesel:
pub struct Download {
id: i32,
version_id: i32,
downloads: i32,
counted: i32,
date: SystemTime,
}
impl Download {
fn from_row(row: &Row) -> Download {
Download {
id: row.get("id"),
version_id: row.get("version_id"),
downloads: row.get("downloads"),
counted: row.get("counted"),
date: row.get("date"),
}
}
}
Inserting Data
It’s not just about reading data. Diesel makes it easy to use structs for new records.
#[derive(Insertable)]
#[diesel(table_name = users)]
struct NewUser<'a> {
name: &'a str,
hair_color: Option<&'a str>,
}
let new_users = vec![
NewUser { name: "Sean", hair_color: Some("Black") },
NewUser { name: "Gordon", hair_color: None },
];
insert_into(users)
.values(&new_users)
.execute(&mut connection);
INSERT INTO users (name, hair_color) VALUES
('Sean', 'Black'),
('Gordon', DEFAULT)
Updating Data
Diesel’s codegen can generate several ways to update a row, letting you encapsulate your logic in the way that makes sense for your app.
Modifying a struct:
post.published = true;
post.save_changes(&mut connection);
One-off batch changes:
update(users.filter(email.like("%@spammer.com")))
.set(banned.eq(true))
.execute(&mut connection)
Using a struct for encapsulation:
update(Settings::belonging_to(current_user))
.set(&settings_form)
.execute(&mut connection)
Ergonomic Multidatabase support
Diesel allows to ergonomically abstract over different database backends while keeping all of it’s compile time guarantees.
#[derive(diesel::MultiConnection)]
enum DatabaseConnection {
Sqlite(diesel::SqliteConnection),
Postgres(diesel::PgConnection),
}
let mut connection = DatabaseConnection::establish("postgres://localhost/diesel")?;
let all_users = users::table.load::<User>(connection)?;
match connection {
DatabaseConnection::Sqlite(connection) => {
perform_sqlite_specific_query(connection)?;
}
DatabaseConnection::Postgres(connection) => {
perform_postgres_specific_query(connection)?;
}
}
Ergonomic Raw SQL
There will always be certain queries that are just easier to write as raw SQL, or can’t be expressed with the query builder. Even in these cases, Diesel provides an easy to use API for writing raw SQL.
#[derive(QueryableByName)]
#[diesel(table_name = users)]
struct User {
id: i32,
name: String,
organization_id: i32,
}
sql_query(include_str!("complex_users_by_organization.sql"))
.bind::<Integer, _>(organization_id)
.bind::<BigInt, _>(offset)
.bind::<BigInt, _>(limit)
.load::<User>(&mut conn)?;
Contribute to Diesel
Help us build the most productive way to interact with databases in Rust.
Documentation
Improve our guides, tutorials, and API docs to make Diesel accessible.
Core Engine
Add new backends or optimize query builders for peak performance.
Website
Improve the diesel.rs website design, accessibility, and UX.
Community
Help with knowledge sharing and welcoming new users on GitHub.
Sponsors
Your support helps maintain Diesel and ensures it remains the best ORM for the Rust ecosystem.