Inserting typed structure as JSONB in postgres with diesel


#1

Hi,
I’m trying to insert a typed structure as JsonB with diesel (instead of a serde_json::Value) in order to use postgres as document / relational store.
Here is the struct:

#[derive(Debug, Serialize, Deserialize)]
pub struct Body {
    pub text1: String,
    pub text2: String,
}

#[derive(Debug, Identifiable)]
pub struct Post {
    pub id: i32,
    pub title: String,
    pub body: Body,
    pub published: bool,
}

#[derive(Insertable)]
#[table_name="posts"]
pub struct NewPost {
    pub title: String,
    pub body: Body,
}

with NewPost the struct that I try to insert (note that I can successfully retrieve Post using diesel posts.limit(5) .load::<models::Post>(&connection)).

the error is

error[E0277]: the trait bound `models::Body: diesel::query_builder::QueryFragment<_>` is not satisfied
  --> src/main.rs:34:10
   |
34 |         .get_result(conn)
   |          ^^^^^^^^^^ the trait `diesel::query_builder::QueryFragment<_>` is not implemented for `models::Body`
   |
   = note: required because of the requirements on the impl of `diesel::query_builder::QueryFragment<_>` for `&models::Body`
   = note: required because of the requirements on the impl of `diesel::query_builder::QueryFragment<_>` for `diesel::insertable::ColumnInsertValue<schema::posts::columns::body, &models::Body>`
   = note: required because of the requirements on the impl of `diesel::insertable::InsertValues<schema::posts::table, _>` for `diesel::insertable::ColumnInsertValue<schema::posts::columns::body, &models::Body>`
   = note: required because of the requirements on the impl of `diesel::insertable::InsertValues<schema::posts::table, _>` for `(diesel::insertable::ColumnInsertValue<schema::posts::columns::title, diesel::expression::bound::Bound<diesel::sql_types::Text, &std::string::String>>, diesel::insertable::ColumnInsertValue<schema::posts::columns::body, &models::Body>)`
   = note: required because of the requirements on the impl of `diesel::query_builder::QueryFragment<_>` for `diesel::query_builder::ValuesClause<(diesel::insertable::ColumnInsertValue<schema::posts::columns::title, diesel::expression::bound::Bound<diesel::sql_types::Text, &std::string::String>>, diesel::insertable::ColumnInsertValue<schema::posts::columns::body, &models::Body>), schema::posts::table>`
   = note: required because of the requirements on the impl of `diesel::query_builder::QueryFragment<_>` for `diesel::query_builder::InsertStatement<schema::posts::table, diesel::query_builder::ValuesClause<(diesel::insertable::ColumnInsertValue<schema::posts::columns::title, diesel::expression::bound::Bound<diesel::sql_types::Text, &std::string::String>>, diesel::insertable::ColumnInsertValue<schema::posts::columns::body, &models::Body>), schema::posts::table>, diesel::query_builder::insert_statement::Insert, diesel::query_builder::returning_clause::ReturningClause<(schema::posts::columns::id, schema::posts::columns::title, schema::posts::columns::body, schema::posts::columns::published)>>`
   = note: required because of the requirements on the impl of `diesel::query_dsl::LoadQuery<_, _>` for `diesel::query_builder::InsertStatement<schema::posts::table,diesel::query_builder::ValuesClause<(diesel::insertable::ColumnInsertValue<schema::posts::columns::title, diesel::expression::bound::Bound<diesel::sql_types::Text, &std::string::String>>, diesel::insertable::ColumnInsertValue<schema::posts::columns::body, &models::Body>), schema::posts::table>>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`

But as I understand QueryFragment is private so as being new to Rust I’m not sure how to proceed.

I want to use a typed struct for the field body instead of a serde_json::Value to not have to Serialize / Deserialize evey time I use the field.

You can find the complete code for the model here:

and the line throwing the error here:

What is the right way to insert the struct NewPost with a struct field Body as JSONB ?

Thank you in advance for any help.


#2

Solved using https://github.com/terry90/diesel_as_jsonb