diesel README

The project's README from github.com/diesel-rs/diesel. As one markdown file: README.md.

diesel logo

A safe, extensible ORM and Query Builder for Rust

Build Status Crates.io

API Documentation: latest release – main branch

Homepage

Diesel gets rid of the boilerplate for database interaction and eliminates runtime errors without sacrificing performance. It takes full advantage of Rust's type system to create a low overhead query builder that "feels like Rust."

Supported databases:

  1. PostgreSQL
  2. MySQL
  3. SQLite
  4. MariaDB

You can configure the database backend in Cargo.toml:

[dependencies]
diesel = { version = "<version>", features = ["<postgres|mysql|sqlite>"] }

Getting Started

Find our extensive Getting Started tutorial at https://diesel.rs/guides/getting-started. Guides on more specific features are coming soon.

Getting help

If you run into problems, you can come ask for help at in our GitHub Discussions forum. This is also the right place to propose new features or show your applications.

Usage

Simple queries

Simple queries are a complete breeze. Loading all users from a database:

users::table.load(&mut connection)

Executed SQL:

SELECT * FROM users;

Loading all the posts for a user:

Post::belonging_to(user).load(&mut connection)

Executed SQL:

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)?;

Executed SQL:

SELECT version_downloads.* FROM 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.

That means you can write this:

#[derive(Queryable, Selectable)]
#[diesel(table_name = downloads)]
pub struct Download {
    id: i32,
    version_id: i32,
    downloads: i32,
    counted: i32,
    date: SystemTime,
}

Instead of this 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);

Executed SQL:

INSERT INTO users (name, hair_color) VALUES
  ('Sean', 'Black'),
  ('Gordon', DEFAULT)

If you need data from the rows you inserted, just change execute to get_result or get_results. Diesel will take care of the rest.

let new_users = vec![
    NewUser { name: "Sean", hair_color: Some("Black") },
    NewUser { name: "Gordon", hair_color: None },
];

let inserted_users = insert_into(users)
    .values(&new_users)
    .get_results::<User>(&mut connection);

Executed SQL:

INSERT INTO users (name, hair_color) VALUES
  ('Sean', 'Black'),
  ('Gordon', DEFAULT)
  RETURNING *

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)

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,
}

// Using `include_str!` allows us to keep the SQL in a
// separate file, where our editor can give us SQL specific
// syntax highlighting.
sql_query(include_str!("complex_users_by_organization.sql"))
    .bind::<Integer, _>(organization_id)
    .bind::<BigInt, _>(offset)
    .bind::<BigInt, _>(limit)
    .load::<User>(&mut conn)?;

Code of conduct

Anyone who interacts with Diesel in any space, including but not limited to this GitHub repository, must follow our code of conduct.

License

Licensed under either of these:

Contributing

Before contributing, please read the contributors guide for useful information about setting up Diesel locally, coding style and common abbreviations.

Unless you explicitly state otherwise, any contribution you intentionally submit for inclusion in the work, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.

Notable Sponsors and Supporters

We would like to thank all of the sponsors supporting the work on Diesel. Notable large sponsors are:


NLNet Foundation

Prototype Fund

GitHub Secure Open Source Fund

NGI Zero Core

Federal Ministry of Research, Technology and Space (Germany)

GiGa Infosystems GmbH

Bytebase - Open-source Database DevSecOps

Additionally we would like to thank all persons sponsoring the project on GitHub. Without them developing Diesel wouldn't be possible.

diesel (diesel-rs/diesel)

Searching Database…

14.2K ·GitHub
这是什么东西?Diesel 是一个安全、可扩展的 Rust ORM 和查询构建器。它消除了数据库相关的样板代码和运行时错误,又不牺牲性能,借助 Rust 的类型系统,让查询“用起来就像 Rust 本身一样”。
所以它是一个要构建进我 Rust 应用里的库,而不是独立工具,对吧?对——它是一个作为依赖添加的 Rust crate。你在 Cargo.toml 里选择它所针对的数据库后端,之后你的代码就通过 Diesel 的 API 来构建和执行查询。
把它加到现有项目里要做哪些事?在 Cargo.toml 中把 Diesel 添加为依赖并在那里配置后端,然后跟着内容详尽的入门教程走一遍。针对更具体功能的指南也即将推出。
我可以把它连接到哪些数据库?四种:PostgreSQL、MySQL、SQLite 和 MariaDB,每一种都可以作为可选后端来支持。
这些类型系统层面的检查会让查询在运行时变慢吗?README 声称没有这方面的代价:Diesel 是一个开销极低的查询构建器,复杂查询也是“零成本”的,所以编译期的安全检查不会损失性能。
我可以免费使用它吗,包括商业项目?可以。Diesel 同时以 Apache 2.0 和 MIT 双许可证发布,你可以为项目任选其中一种;两者都允许商业使用。
如果我需要的查询构建器表达不了,怎么办?Diesel 正好为此提供了一个易用的原生 SQL API——适用于手写 SQL 更简单、或者构建器无法表达该查询的情况。
我要写多少行转成结构体的映射代码?几乎不用写。Diesel 的代码生成会替你生成这些样板代码,你只需要专注于业务逻辑,不用手动把 SQL 行数据搬进搬出结构体。
插入数据之后,我怎么读回自动生成的值,比如 ID?不要用 execute,改用 get_result 或 get_results,Diesel 就会返回你插入的那几行数据。
更新一行数据有哪几种方式?代码生成可以生成好几种风格:修改一个结构体、一次性的批量修改,或者把修改封装到一个专门的结构体里——选哪种都行,看你的应用那部分更适合哪种。
What are similar projects?orm, ent, kysely, mybatis-plus, sequelize, efcore, sqlc, sqlalchemy
Creator
diesel-rs
Size
167.1 MB
Stars
14.2K
Age
11y
Commits · 90 Days