Reputation: 1940
I have this struct:
#[table_name = "clients"]
#[derive(Serialize, Deserialize, Queryable, Insertable, Identifiable, Associations)]
pub struct Client {
pub id: Option<i64>,
pub name: String,
pub rank: Option<i64>,
}
and the following implementation:
impl Client {
pub fn get(name: String, connection: &PgConnection) -> Option<Self> {
match clients::table
.filter(clients::name.eq(&name))
.limit(1)
.load::<Client>(connection)
{
Ok(clients) => Some(clients[0]),
Err(_) => None,
}
}
}
which gives me the following error:
.load::<Client>(connection) {
^^^^ the trait `diesel::Queryable<diesel::sql_types::BigInt, _>` is not implemented for `std::option::Option<i64>`
Upvotes: 5
Views: 2706
Reputation: 1670
For me the issue was not realising that diesel maps fields based entirely on the order of fields in the struct. It completely ignores field names.
If your struct has fields defined in a different order to the schema.rs
file then it will map them incorrectly and cause type errors.
https://docs.diesel.rs/diesel/deserialize/trait.Queryable.html#deriving
When this trait is derived, it will assume that the order of fields on your struct match the order of the fields in the query. This means that field order is significant if you are using
#[derive(Queryable)]
. Field name has no effect.
Upvotes: 0
Reputation: 42849
Your error message says that you cannot query a BigInt
(a 64 bits int) into an Option<i64>
. That is because you forgot to say that id
is nullable in your table declaration. It must look like:
table! {
clients {
id -> Nullable<BigInt>,
name -> Text,
rank -> Nullable<BigInt>,
}
}
You can see the implementation of Queryable
you are looking for in the documentation.
Upvotes: 9