Diesel 2.1.0 已正式发布,此版本开发周期总共 9 个月,42 名贡献者提交了超过 380 个 commit。
Diesel 是一个安全可扩展的 Rust ORM 框架和查询构建工具。Diesel 可避免运行时错误,提供最好的性能。
2.1.0 引入了多项新特性,并改进了现有功能。它引入了对通过 Diesel CLI 根据schema.rs
文件和数据库之间的差异生成迁移的支持信息。
Diesel derived 现在提供了一个#[derive(MultiConnection)]
derive 宏,允许轻松地将不同的数据库连接组合成一个单独的枚举,可自己实现Connection
。 MySQL 后端通过ON DUPLICATE KEYS
语法获得对upsert
查询的支持。
此外还提供了新工具来改进为常见错误情况生成的复杂错误消息。详情查看 Changelog。
2.x 系列重写了大部分内部结构。因此这是新的大版本,它还包含许多破坏兼容性的变化,具体处理方案查看迁移指南。
更新亮点
- 支持
MultiConnection
Diesel 现在包含一个 #[derive(MultiConnection)]
proc 宏派生,它允许在单个应用程序中轻松支持多个数据库后端。它可以应用于不同连接的枚举:
#[derive(diesel::MultiConnection)]
pub enum AnyConnection {
Postgresql(diesel::PgConnection),
Mysql(diesel::MysqlConnection),
Sqlite(diesel::SqliteConnection),
}
之后 AnyConnection
类型可以用作普通连接:
fn use_multi(conn: &mut AnyConnection) -> QueryResult<()> {
// Use the connection enum as any other connection type
// for inserting/updating/loading/…
diesel::insert_into(users::table)
.values(users::name.eq("Sean"))
.execute(conn)?;
let users = users::table.load::<(i32, String)>(conn)?;
Ok(())
}
- 对 MySQL 后端的 Upsert 支持
Diesel 2.1 使用现有的upsert
框架添加了对MySQL 后端INSERT INTO … ON DUPLICATE KEYS …
查询的支持。现在支持使用 diesel 提供的 DSL 编写此类查询:
diesel::insert_into(users)
.values(&user2)
.on_conflict(diesel::dsl::DuplicatedKeys)
.do_update()
.set(name.eq("I DONT KNOW ANYMORE"))
.execute(conn)?;
- 改进错误信息
此版本改进了 rustc 为常见的 Diesel 问题生成的错误消息。
比如下面的示例:
table! {
users {
id -> Integer,
name -> Text,
}
}
#[derive(Queryable)]
struct User {
name: String,
id: i32,
}
users::table.load::<User>(&mut conn)
将生成以下错误消息:
error[E0277]: the trait bound `(diesel::sql_types::Integer, diesel::sql_types::Text): load_dsl::private::CompatibleType<User, Mysql>` is not satisfied
--> src/main.rs:20:31
|
20 | users::table.load::<User>(&mut conn);
|---- ^^^^^^^^^ the trait `load_dsl::private::CompatibleType<User, Mysql>` is not implemented for `(diesel::sql_types::Integer, diesel::sql_types::Text)`
||
|required by a bound introduced by this call
|
= help: the following other types implement trait `load_dsl::private::CompatibleType<U, DB>`:
(ST0, ST1)
(ST0, ST1, ST2)
(ST0, ST1, ST2, ST3)
(ST0, ST1, ST2, ST3, ST4)
(ST0, ST1, ST2, ST3, ST4, ST5)
(ST0, ST1, ST2, ST3, ST4, ST5, ST6)
(ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7)
(ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST8)
and 24 others
= note: required for `users::table` to implement `LoadQuery<'_, _, User>`
note: required by a bound in `diesel::RunQueryDsl::load`
--> /home/weiznich/.cargo/git/checkouts/diesel-6e3331fb3b9331ec/ef6252e/diesel/src/query_dsl/mod.rs:1543:15
|
1543 | Self: LoadQuery<'query, Conn, U>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `diesel::RunQueryDsl::load`
在新版本则生成以下错误信息:
error[E0277]: the trait bound `i32: FromSql<diesel::sql_types::Text, Mysql>` is not satisfied
--> src/main.rs:13:11
|
13 | name: i32,
| ^^^ the trait `FromSql<diesel::sql_types::Text, Mysql>` is not implemented for `i32`
|
= help: the trait `FromSql<diesel::sql_types::Integer, Mysql>` is implemented for `i32`
= note: required for `i32` to implement `diesel::Queryable<diesel::sql_types::Text, Mysql>`
= note: required for `i32` to implement `FromSqlRow<diesel::sql_types::Text, Mysql>`
= help: see issue #48214
Release Notes