I'm fairly new to Diesel and wanted to add it to a Rocket project. I followed the tutorials then decided to create tables and queries on my own.
So here is the issue : when I try to do a simple request like SELECT * FROM ... WHERE id = ?
using the query builder, I get compile-time errors that I cannot understand.
Here is the error:
error[E0277]: the trait bound `(i32, std::string::String, std::string::String): FromStaticSqlRow<(diesel::sql_types::Nullable<diesel::sql_types::Integer>, diesel::sql_types::Text, diesel::sql_types::Text), Sqlite>` is not satisfied
--> src/dbal/quote_subject.rs:26:12
|
26 | .first(db)
| ----- ^^ the trait `FromStaticSqlRow<(diesel::sql_types::Nullable<diesel::sql_types::Integer>, diesel::sql_types::Text, diesel::sql_types::Text), Sqlite>` is not implemented for `(i32, std::string::String, std::string::String)`
| |
| required by a bound introduced by this call
|
= 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
note: required for `QuoteSubject` to implement `diesel::Queryable<(diesel::sql_types::Nullable<diesel::sql_types::Integer>, diesel::sql_types::Text, diesel::sql_types::Text), Sqlite>`
--> src/models.rs:5:24
|
5 | #[derive(Identifiable, Queryable, Serialize, Deserialize, Debug, Clone)]
| ^^^^^^^^^
6 | #[diesel(table_name = quote_subject)]
7 | pub struct QuoteSubject {
| ^^^^^^^^^^^^
= note: required for `QuoteSubject` to implement `FromSqlRow<(diesel::sql_types::Nullable<diesel::sql_types::Integer>, diesel::sql_types::Text, diesel::sql_types::Text), Sqlite>`
= note: required for `(diesel::sql_types::Nullable<diesel::sql_types::Integer>, diesel::sql_types::Text, diesel::sql_types::Text)` to implement `load_dsl::private::CompatibleType<QuoteSubject, Sqlite>`
= note: required for `SelectStatement<FromClause<schema::quote_subject::table>, diesel::query_builder::select_clause::DefaultSelectClause<FromClause<schema::quote_subject::table>>, diesel::query_builder::distinct_clause::NoDistinctClause, diesel::query_builder::where_clause::WhereClause<expression::grouped::Grouped<expression::operators::Eq<schema::quote_subject::columns::id, _>>>, diesel::query_builder::order_clause::NoOrderClause, diesel::query_builder::limit_offset_clause::LimitOffsetClause<diesel::query_builder::limit_clause::LimitClause<expression::bound::Bound<BigInt, i64>>, diesel::query_builder::offset_clause::NoOffsetClause>>` to implement `LoadQuery<'_, diesel::SqliteConnection, QuoteSubject>`
note: required by a bound in `first`
--> /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/diesel-2.0.2/src/query_dsl/mod.rs:1736:22
|
1736 | Limit<Self>: LoadQuery<'query, Conn, U>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `first`
= note: this error originates in the derive macro `Queryable` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0277`.
error: could not compile `le-saviez-vous` due to previous error
FYI, I'm using SQLite for this project.
Here is my code :
/// src/dbal/quote_subject.rs
use crate::schema::quote_subject::dsl::*;
use crate::models::QuoteSubject;
use diesel::{SqliteConnection, QueryDsl, RunQueryDsl};
use crate::helpers::database;
use diesel::prelude::*;
/// this function aims to get one QuoteSubject object from table `quote_subject` with it's Id.
pub fn find(object_id: i64) -> QuoteSubject {
let db: &mut SqliteConnection = &mut get_connection();
quote_subject
.filter(id.eq(object_id.into()))
.first(db)
.unwrap()
}
/// src/models.rs
use diesel::prelude::*;
use serde::{Serialize, Deserialize};
use crate::schema::*;
#[derive(Identifiable, Queryable, Serialize, Deserialize, Debug, Clone)]
#[diesel(table_name = quote_subject)]
pub struct QuoteSubject {
pub id: i32,
pub quote_singular: String,
pub quote_plural: String
}
#[derive(Queryable)]
pub struct QuoteVerb {
pub id: i32,
pub quote_singular: String,
pub quote_plural: String
}
#[derive(Queryable)]
pub struct QuoteDescription {
pub id: i32,
pub quote_singular: String,
pub quote_plural: String
}
/// src/schema.rs
diesel::table! {
quote_description (id) {
id -> Nullable<Integer>,
quote_singular -> Text,
quote_plural -> Text,
}
}
-- the migration used to create the table inside the SQLite database
CREATE TABLE "quote_subject" (
id INTEGER PRIMARY KEY AUTOINCREMENT,
quote_singular VARCHAR (255) NOT NULL,
quote_plural VARCHAR (255) NOT NULL
);
Any idea on how to solve this ?
Tried various searches and some code replacement following git issues but could not make it to work.
CodePudding user response:
I'll simplify the error message:
the trait bound `(i32, String, String): FromStaticSqlRow<(Nullable<Integer>, Text, Text), Sqlite>` is not satisfied
Can you spot it now? This will try to construct an i32
from a Nullable<Integer>
but this is not possible because the value could be NULL
.
Now, its not going to be NULL
because you have INTEGER PRIMARY KEY
which implies NOT NULL
, but the schema.rs
still has the id
column marked as Nullable
.
Change your schema to declare id -> Integer
instead.