Jamie Davenport
Jamie Davenport

Reputation: 371

Rust/Diesel: How to query and insert into postgres tables which have uuid

I have the following schema generated by Diesel:

table! {
user (id) {
    id -> Uuid,
    name -> Text
}

and the associated model

use diesel::{
    self,
    Queryable,
    Insertable,
};
use diesel::prelude::*;
use diesel::sql_types::Uuid;
use super::schema::user;

#[derive(Queryable)]
pub struct User {
    pub id: Uuid,
    pub name: String,
}

impl User {

    pub fn get(id: i32, connection: &PgConnection) -> Vec<User> {
        user::table.load::<User>(connection).unwrap()
    }
}

I get an error when I try to compile this which says:

21 |         user::table.load::<User>(connection).unwrap()                                                                                                                              
   |                         ^^^^ the trait `diesel::Queryable<diesel::sql_types::Uuid, diesel::pg::Pg>` is not implemented for `diesel::sql_types::Uuid` 

If I try to insert I get a similar error saying that Expression is not implemented.

Could this be a problem with my dependencies or something I may have forgotten to add to the model?

[dependencies]
rocket = "0.4.0-rc.1"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
diesel = { version = "1.0.0", features = ["postgres", "uuid"] }
r2d2 = "*"
r2d2-diesel = "*"

[dependencies.rocket_contrib]
version = "0.4.0-rc.1"
default-features = false
features = ["json", "diesel_postgres_pool", "uuid"]

Upvotes: 21

Views: 12126

Answers (3)

Ismael Terreno
Ismael Terreno

Reputation: 1121

I think the issue here is the use diesel::sql_types::Uuid; where has a trait that is not required so instead you can use purely a uuid crate. So you can use on one side the diesel feature "uuid" to generate the entity and the uuid crate to declare the struct: So you will have the following:

[dependencies]
diesel = { version = "2.1.0", features = ["postgres", "uuid"] }
uuid = "1.8.0"
... rest of dependencies

And in the struct

use diesel::prelude::*;
use uuid::Uuid;

#[derive(Queryable, Selectable)]
#[diesel(table_name = crate::schema::user)]
#[diesel(check_for_backend(diesel::pg::Pg))]
pub struct User {
    pub id: Uuid,
    pub topic: String,
    pub body: String,
    pub read: bool,
}

Upvotes: 0

danitrod
danitrod

Reputation: 431

Just spent a lot of time with this problem as well. It looks like as of Diesel 1.4.5, you can add the latest version of uuid, but you have to specify the uuidv07 feature on Diesel.

Your Cargo.toml should look something like this:

uuid = { version = "0.8.2", features = ["serde", "v4"] }
diesel = { version = "1.4.5", features = ["chrono", "postgres", "r2d2", "uuidv07"] }

Source: https://github.com/diesel-rs/diesel/issues/2348

Note: Also, like @canab said, the Uuid type on the struct should be from the uuid library, not the Diesel SQL type.

Upvotes: 20

canab
canab

Reputation: 131

The type in the struct needs to be a Rust type rather than a SQL type, specifically Uuid from the uuid crate (in Diesel 1.3, only version 0.6 is supported by Diesel). In the code from the question, the Uuid is expanded to a diesel::sql_types::Uuid

#[derive(Queryable)]
pub struct User {
    pub id: uuid::Uuid,
    pub name: String,
}

Upvotes: 13

Related Questions