Search code examples
rustrust-diesel

Diesel "get_results" gives a trait bound error


I am trying to make an Actix API with Diesel, and in making the first endpoint (/books/create), I am having trouble trying to get the inserted value back into my code.

This is my insert:

use diesel::prelude::*;
use crate::models::Book;
use crate::schema::books;
use crate::db;


pub fn create_book(book: &Book) -> Book {
    
    let mut connection: SqliteConnection = db::establish_connection();
    let result: QueryResult<Book> = diesel::insert_into(books::table)
        .values([book])
        .get_result::<Book>(&mut connection);
        
    
    result.unwrap()
}

This is the error, which I wrapped in a pastebin since it's too long for Stackoverflow: https://pastebin.com/Evq6tUYq

I wonder if it can be a problem of the schema or model, but they seem to be okay'ish and don't have mismatching values, as far as I know:

use diesel::prelude::*;
use serde::{Serialize, Deserialize};    
use crate::schema::books;

#[derive(Queryable, Serialize, Deserialize, Insertable)]
#[diesel(table_name = books)]
pub struct Book {
    pub id: i32,
    pub title: String,
    pub author: String,
    pub creation_date: Option<String>,
    pub publishing_house: Option<String>,
    pub release_date: Option<String>,
    pub cover_image: Option<String>
}



diesel::table! {
    books (id) {
        id -> Integer,
        title -> Text,
        author -> Text,
        publishing_house -> Nullable<Text>,
        release_date -> Nullable<Text>,
        cover_image -> Nullable<Text>,
        creation_date -> Nullable<Text>,
    }
}

Where is the error? What's missing?


Solution

  • It's impossible to answer this question as it is missing important details like the used diesel version, and the enabled feature flags for diesel.

    The underlying problem is that .get_result() uses INSERT INTO … RETURNING SQL statements internally. These are only supported by Sqlite 3.35 or newer. As of this support for such statements is behind a separate diesel feature flag. You need to enable the returning_clauses_for_sqlite_3_35 feature flag.

    That by itself will not fix the issue. .values([book]) creates a array with one element and tries to insert that. This will cause diesel to use a batch insert statement, which normally allows to insert more than one element at once. While this is supported for the sqlite backend it cannot be used in combination with the returning support described above, as SQLite is missing another SQL feature here (using the DEFAULT keyword to signal that a certain value should be replaced by the corresponding database default value). In your case this can be fixed by just calling .values(&book), which constructs an ordinary single row insert.