Rust Diesel中load方法类型参数不兼容问题解决
Diesel查询用户凭证时的类型不兼容问题
我尝试使用Diesel编写一个简单查询,匹配给定凭证的用户。查阅Diesel文档后,我认为需要在load方法使用的结构体上添加Queryable宏,但出现了类型不兼容错误。
编译错误信息
error[E0277]: the trait bound `(Integer, Text, Text, Text, diesel::sql_types::Timestamp): load_dsl::private::CompatibleType<dal::models::users::UserView<'_>, _>` is not satisfied --> src/services/user.rs:16:27 | 16 | .load::<UserView>(connection); | ---- ^^^^^^^^^^ the trait `load_dsl::private::CompatibleType<dal::models::users::UserView<'_>, _>` is not implemented for `(Integer, Text, Text, Text, diesel::sql_types::Timestamp)` | | | 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 `SelectStatement<FromClause<table>, DefaultSelectClause<FromClause<table>>, NoDistinctClause, WhereClause<Grouped<And<Grouped<Eq<username, ...>>, ...>>>>` to implement `LoadQuery<'_, _, dal::models::users::UserView<'_>>` = note: the full type name has been written to '/home/pop/Documents/code/PECI-05-2022-23/auth/target/debug/deps/auth-955be7812e7a3b43.long-type-7337842634617248670.txt' note: required by a bound in `diesel::RunQueryDsl::load` --> /home/pop/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.0.3/src/query_dsl/mod.rs:1499:15 | 1499 | Self: LoadQuery<'query, Conn, U>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::load` error[E0277]: the trait bound `dal::models::users::UserView<'_>: FromSqlRow<_, _>` is not satisfied --> src/services/user.rs:16:27 | 16 | .load::<UserView>(connection); | ---- ^^^^^^^^^^ the trait `FromSqlRow<_, _>` is not implemented for `dal::models::users::UserView<'_>` | | | required by a bound introduced by this call | = help: the following other types implement trait `FromSqlRow<ST, DB>`: <(T1, T0) as FromSqlRow<(ST1, Untyped), __DB>> <(T1, T2, T0) as FromSqlRow<(ST1, ST2, Untyped), __DB>> <(T1, T2, T3, T0) as FromSqlRow<(ST1, ST2, ST3, Untyped), __DB>> <(T1, T2, T3, T4, T0) as FromSqlRow<(ST1, ST2, ST3, ST4, Untyped), __DB>> <(T1, T2, T3, T4, T5, T0) as FromSqlRow<(ST1, ST2, ST3, ST4, ST5, Untyped), __DB>> <(T1, T2, T3, T4, T5, T6, T0) as FromSqlRow<(ST1, ST2, ST3, ST4, ST5, ST6, Untyped), __DB>> <(T1, T2, T3, T4, T5, T6, T7, T0) as FromSqlRow<(ST1, ST2, ST3, ST4, ST5, ST6, ST7, Untyped), __DB>> <(T1, T2, T3, T4, T5, T6, T7, T8, T0) as FromSqlRow<(ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST8, Untyped), __DB>> and 23 others = note: required for `SelectStatement<FromClause<table>, DefaultSelectClause<FromClause<table>>, NoDistinctClause, WhereClause<Grouped<And<Grouped<Eq<username, ...>>, ...>>>>` to implement `LoadQuery<'_, _, dal::models::users::UserView<'_>>` = note: the full type name has been written to '/home/pop/Documents/code/PECI-05-2022-23/auth/target/debug/deps/auth-955be7812e7a3b43.long-type-7337842634617248670.txt' note: required by a bound in `diesel::RunQueryDsl::load` --> /home/pop/.cargo/registry/src/index.crates.io-6f17d22bba15001f/diesel-2.0.3/src/query_dsl/mod.rs:1499:15 | 1499 | Self: LoadQuery<'query, Conn, U>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `RunQueryDsl::load` For more information about this error, try `rustc --explain E0277`. warning: `auth` (bin "auth") generated 3 warnings error: could not compile `auth` (bin "auth") due to 2 previous errors; 3 warnings emitted
相关代码
登录函数
pub fn login(user_credentials: UserLogin) -> bool { use crate::dal::schema::users::dsl::*; let connection = &mut get_connection(); let result = users .filter(username.eq(user_credentials.username)) .filter(password.eq(user_credentials.password)) .load::<UserView>(connection); match result { Ok(query_res) => return query_res.len() == 1, Err(_) => return false } }
初始的UserView结构体
#[derive(Queryable)] pub struct UserView<'a> { pub user_id: i32, pub username: &'a str, pub email: &'a str, pub created_on: SystemTime }
Users表Schema定义
diesel::table! { users (user_id) { user_id -> Int4, username -> Varchar, password -> Varchar, email -> Varchar, created_on -> Timestamp, } }
Cargo.toml依赖配置
[package] name = "auth" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] rocket = { version = "0.5.0-rc.2", features= ["json"]} diesel = { version = "2.0.1", features = ["postgres", "chrono"] } dotenv = "0.15.0" chrono = "^0" serde = { version = "1.0.117", features = ["derive"] } serde_json = "1.0.59"
问题解决
将UserView结构体修改为以下形式后问题解决。错误原因是之前误以为load可以只选择指定字段,但当前查询是查询users表的所有字段,因此结构体必须包含表中所有列,同时不能使用引用类型(如&str),需要使用拥有所有权的类型(如String):
#[derive(Queryable)] pub struct UserView { pub user_id : i32, pub username : String, pub password : String, pub email: String, pub created_on: SystemTime, }
内容的提问来源于stack exchange,提问作者João Machado
相关产品推荐
相关产品推荐

