Diesel UUID Problem Note

背景描述

在使用 Dieseluuid 开发的过程中, 使用发生报错:

1
2
3
4
5
6
7
8
9
10
11
error[E0277]: the trait bound `uuid::Uuid: diesel::Queryable<diesel::sql_types::Uuid, _>` is not satisfied
--> src/models.rs:45:14
|
45 | .load::<App>(conn)
| ^^^^ the trait `diesel::Queryable<diesel::sql_types::Uuid, _>` is not implemented for `uuid::Uuid`
|
= note: required because of the requirements on the impl of `diesel::Queryable<(diesel::sql_types::Uuid, diesel::sql_types::Text), _>` for `(uuid::Uuid, std::string::String)`
= note: required because of the requirements on the impl of `diesel::Queryable<(diesel::sql_types::Uuid, diesel::sql_types::Text), _>` for `models::App`
= note: required because of the requirements on the impl of `diesel::query_dsl::LoadQuery<_, models::App>` for `diesel::query_builder::SelectStatement<schema::app::table, dies
el::query_builder::select_clause::DefaultSelectClause, diesel::query_builder::distinct_clause::NoDistinctClause, diesel::query_builder::where_clause::NoWhereClause, diesel::query
_builder::order_clause::NoOrderClause, diesel::query_builder::limit_clause::LimitClause<diesel::expression::bound::Bound<diesel::sql_types::BigInt, i64>>>`

代码如下:

Cargo.toml:

1
2
3
[dependencies]
diesel = { version = "1.4.2", features = ["postgres", "uuid"] }
uuid = { version = "0.7.4", features = ["v4"] }

schema.rs

1
2
3
4
5
6
table! {
app (id) {
id -> Uuid,
jwt_secret -> Varchar,
}
}

models.rs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
use diesel::pg::PgConnection;
use diesel::prelude::*;
use uuid::Uuid;

use crate::schema::app;
use crate::token::{create_claims, create_jwt_secret, encode_token, Claims, TokenError};

#[derive(Queryable)]
struct App {
id: Uuid,
jwt_secret: String,
}

#[derive(Insertable)]
#[table_name = "app"]
struct NewApp {
jwt_secret: String,
}

impl App {
fn get_by_id(&self, conn: &PgConnection) -> Vec<App> {
app::table
.limit(1)
.load::<App>(conn)
.expect("Error loading app")
}
}

经过

在往上查询未果, 经人提点可能是项目中 uuid 和版本不一致的问题导致的.

UUID 降级

查看 Diesel 的 diesel/Cargo.toml at 1.4.x · diesel-rs/diesel · GitHub 发现 Diesel 依赖的 uuid 版本>=0.2.0, <0.7.0.

1
uuid = { version = ">=0.2.0, <0.7.0", optional = true, features = ["use_std"] }

而我在项目中使用的 uuid0.7.4. 尝试将 uuid 降级到 0.6.

上述问题不再报错, 不过有一个新的报错出现:

1
2
3
4
5
error[E0599]: no method named `to_simple` found for type `uuid::Uuid` in the current scope
--> src/models.rs:37:45
|
37 | let claims = create_claims(&self.id.to_simple().to_string());
| ^^^^^^^^^ help: there is a method with a similar name: `simple`

可以推断, uuid 在 0.6 到 0.7 的过程中有较大的功能改变. 那新问题就来了:

我希望使用 uuid 最新版本的能力.

修改 Dependence

好消息是我在 Cargo.toml 紧接着的一行发现了一个 dependence: uuidv07:

1
uuidv07 = { version = "0.7.0", optional = true, package = "uuid"}

从配置信息可以看到, 这个 uuidv07 同样使用的是 uuid 包 (package = "uuid"). 但是版本为 “0.7.0” (version = "0.7.0").

尝试修改本地项目的 Cargo.toml 文件:

1
2
3
[dependencies]
diesel = { version = "1.4.2", features = ["postgres", "uuidv07"] }
uuid = { version = "0.7.4", features = ["v4"] }

测试通过!

结论

网上几乎没法找到这个改动相关的问题和解决方案, 甚至文档中都没有提及.

定位问题的能力还是有待提高.

#tech/rust