Derive Macro diesel::prelude::Queryable

source ·
#[derive(Queryable)]
{
    // Attributes available to this derive:
    #[diesel]
    #[column_name]
}
Expand description

Implements Queryable to load the result of statically typed queries

This trait can only be derived for structs, not enums.

Note: When this trait is derived, it will assume that all fields on your struct matches all fields in the query, including the order and count. This means that field order is significant if you’re using #[derive(Queryable)]. Field name has no effect. If you see errors while loading data into a struct that derives Queryable: Consider using [#[derive(Selectable)]] + #[diesel(check_for_backend(YourBackendType))] to check for mismatching fields at compile-time.

To provide custom deserialization behavior for a field, you can use #[diesel(deserialize_as = SomeType)]. If this attribute is present, Diesel will deserialize the corresponding field into SomeType, rather than the actual field type on your struct and then call .try_into to convert it to the actual field type. This can be used to add custom behavior for a single field, or use types that are otherwise unsupported by Diesel. (Note: all types that have Into<T> automatically implement TryInto<T>, for cases where your conversion is not fallible.)

§Attributes

§Optional field attributes

  • #[diesel(deserialize_as = Type)], instead of deserializing directly into the field type, the implementation will deserialize into Type. Then Type is converted via .try_into into the field type. By default, this derive will deserialize directly into the field type

§Examples

If we just want to map a query to our struct, we can use derive.

#[derive(Queryable, PartialEq, Debug)]
struct User {
    id: i32,
    name: String,
}

let first_user = users.first(connection)?;
let expected = User { id: 1, name: "Sean".into() };
assert_eq!(expected, first_user);

If we want to do additional work during deserialization, we can use deserialize_as to use a different implementation.

struct LowercaseString(String);

impl Into<String> for LowercaseString {
    fn into(self) -> String {
        self.0
    }
}

impl<DB> Queryable<Text, DB> for LowercaseString
where
    DB: Backend,
    String: FromSql<Text, DB>
{

    type Row = String;

    fn build(s: String) -> deserialize::Result<Self> {
        Ok(LowercaseString(s.to_lowercase()))
    }
}

#[derive(Queryable, PartialEq, Debug)]
struct User {
    id: i32,
    #[diesel(deserialize_as = LowercaseString)]
    name: String,
}

let first_user = users.first(connection)?;
let expected = User { id: 1, name: "sean".into() };
assert_eq!(expected, first_user);

Alternatively, we can implement the trait for our struct manually.

use schema::users;
use diesel::deserialize::{self, Queryable, FromSqlRow};
use diesel::row::Row;

type DB = diesel::sqlite::Sqlite;

#[derive(PartialEq, Debug)]
struct User {
    id: i32,
    name: String,
}

impl Queryable<users::SqlType, DB> for User
where
   (i32, String): FromSqlRow<users::SqlType, DB>,
{
    type Row = (i32, String);

    fn build((id, name): Self::Row) -> deserialize::Result<Self> {
        Ok(User { id, name: name.to_lowercase() })
    }
}

let first_user = users.first(connection)?;
let expected = User { id: 1, name: "sean".into() };
assert_eq!(expected, first_user);