Home > Software design >  Issues with Rust/Diesel queries
Issues with Rust/Diesel queries

Time:11-06

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.

  • Related