Reputation: 346
I'm trying to use the Diesel crate (version 2.0.2; rustc 1.63.0) for an application and have some code that goes like this:
src/models.rs
use uuid::Uuid;
use diesel::prelude::*;
use crate::schema::entities::dsl::entities;
type DB = diesel::pg::Pg;
#[derive(Queryable, PartialEq, Debug)]
#[diesel(table_name = entities)]
pub struct Entity {
pub id: u16,
pub uuid: Uuid,
pub username: Option<String>
}
impl Entity {
pub fn get_all(connection: &mut PgConnection) -> QueryResult<Vec<Entity>> {
entities.load::<Entity>(connection)
}
}
src/schema.rs
// @generated automatically by Diesel CLI.
diesel::table! {
entities (id) {
id -> Int4,
uuid -> Uuid,
username -> Nullable<Text>,
}
}
diesel::allow_tables_to_appear_in_same_query!(
entities,
);
However, this will not compile. The following errors are thrown when I try:
error[E0277]: the trait bound `(Integer, diesel::sql_types::Uuid, diesel::sql_types::Nullable<diesel::sql_types::Text>): load_dsl::private::CompatibleType<Entity, _>` is not satisfied
--> src/models.rs:20:18
|
20 | entities.load::<Entity>(connection)
| ^^^^ the trait `load_dsl::private::CompatibleType<Entity, _>` is not implemented for `(Integer, diesel::sql_types::Uuid, diesel::sql_types::Nullable<diesel::sql_types::Text>)`
|
= 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 because of the requirements on the impl of `LoadQuery<'_, _, Entity>` for `entities::table`
note: required by a bound in `diesel::RunQueryDsl::load`
--> /home/username/.cargo/registry/src/github.com-1ecc6299db9ec823/diesel-2.0.2/src/query_dsl/mod.rs:1499:15
|
1499 | Self: LoadQuery<'query, Conn, U>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `diesel::RunQueryDsl::load`
error[E0277]: the trait bound `Entity: FromSqlRow<_, _>` is not satisfied
--> src/models.rs:20:18
|
20 | entities.load::<Entity>(connection)
| ^^^^ the trait `FromSqlRow<_, _>` is not implemented for `Entity`
|
= 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 because of the requirements on the impl of `LoadQuery<'_, _, Entity>` for `entities::table`
note: required by a bound in `diesel::RunQueryDsl::load`
--> /home/username/.cargo/registry/src/github.com-1ecc6299db9ec823/diesel-2.0.2/src/query_dsl/mod.rs:1499:15
|
1499 | Self: LoadQuery<'query, Conn, U>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `diesel::RunQueryDsl::load`
According to Diesel's documentation (specifically this page), deriving Queryable should be enough to run functions like load
on entities
.
From the error message, I gather that Diesel's FromSqlRow
trait is not being implemented, but whenever I try to include that in the derive (and remove the conflicting Queryable
derivation), I am only met by another, very similar, set of errors on compilation. A long walk through Diesel's available documentation hasn't helped me understand what is going on or how I might fix it as the typical documentation seems to be "derive it," and a google search is similarly unfruitful. Am I supposed to be implementing any traits by hand here? If so, what might that look like (I cannot find any examples)? Or is there something else I'm missing? More importantly, can anyone explain exactly what this error message is trying to communicate?
EDIT 1: Provide the relevant schema code; had provided it for a different model accidentally.
EDIT 2: Below update with clarified order of properties
Even when I change models.rs to the below to explicitly declare the order in which properties are selected, a similar error (see edit 4) still appears:
use uuid::Uuid;
use diesel::prelude::*;
use crate::schema::entities;
type DB = diesel::pg::Pg;
#[derive(Queryable, PartialEq, Debug)]
#[diesel(table_name = entities)]
pub struct Entity {
pub id: u16,
pub uuid: Uuid,
pub username: Option<String>
}
impl Entity {
pub fn get_all(connection: &mut PgConnection) -> QueryResult<Vec<Entity>> {
entities::dsl::entities
.select((entities::id, entities::uuid, entities::username))
.load::<Entity>(connection)
}
}
I have included the proper feature flags in Cargo.toml.
EDIT 3: Verified that versions are compatible; see changelog for Diesel
EDIT 4: new error that is being thrown on compilation
error[E0277]: the trait bound `(u16, uuid::Uuid, Option<String>): FromStaticSqlRow<(Integer, diesel::sql_types::Uuid, diesel::sql_types::Nullable<diesel::sql_types::Text>), Pg>` is not satisfied
--> src/models.rs:22:14
|
22 | .load(connection)
| ^^^^ the trait `FromStaticSqlRow<(Integer, diesel::sql_types::Uuid, diesel::sql_types::Nullable<diesel::sql_types::Text>), Pg>` is not implemented for `(u16, uuid::Uuid, Option<String>)`
|
= help: the following other types implement trait `FromStaticSqlRow<ST, DB>`:
<(T0,) as FromStaticSqlRow<(ST0,), __DB>>
<(T1, T0) as FromStaticSqlRow<(ST1, ST0), __DB>>
<(T1, T2, T0) as FromStaticSqlRow<(ST1, ST2, ST0), __DB>>
<(T1, T2, T3, T0) as FromStaticSqlRow<(ST1, ST2, ST3, ST0), __DB>>
<(T1, T2, T3, T4, T0) as FromStaticSqlRow<(ST1, ST2, ST3, ST4, ST0), __DB>>
<(T1, T2, T3, T4, T5, T0) as FromStaticSqlRow<(ST1, ST2, ST3, ST4, ST5, ST0), __DB>>
<(T1, T2, T3, T4, T5, T6, T0) as FromStaticSqlRow<(ST1, ST2, ST3, ST4, ST5, ST6, ST0), __DB>>
<(T1, T2, T3, T4, T5, T6, T7, T0) as FromStaticSqlRow<(ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST0), __DB>>
and 24 others
Upvotes: 6
Views: 1453
Reputation: 3435
The linked documentation already gives a pretty strong hint what's wrong in your case:
Note: When this trait is derived, it will assume that all fields on your struct matches all fields in the query, including the order and count. This means that field order is significant if you are using #[derive(Queryable)]. Field name has no effect.
In your case the problem is a mismatch between the type of the id field and the corresponding database type. That's u16
on rust side vs Int4
on database side. According to the diesel documentation of Integer
(Int4
is a type alias for this type), these two types are not compatible. You need to use a i32
in that position.
They are not considered compatible as not all possible database values of a Int4
field fit into a u16
Upvotes: 5