[][src]Derive Macro diesel::deserialize::QueryableByName

#[derive(QueryableByName)]
{
    // Attributes available to this derive:
    #[table_name]
    #[column_name]
    #[sql_type]
    #[diesel]
}

Implements QueryableByName for untyped sql queries, such as that one generated by sql_query

To derive this trait, Diesel needs to know the SQL type of each field. You can do this by either annotating your struct with #[table_name = "some_table"] (in which case the SQL type will be diesel::dsl::SqlTypeOf<table_name::column_name>), or by annotating each field with #[sql_type = "SomeType"].

If you are using #[table_name], the module for that table must be in scope. For example, to derive this for a struct called User, you will likely need a line such as use schema::users;

If the name of a field on your struct is different than the column in your table! declaration, or if you are deriving this trait on a tuple struct, you can annotate the field with #[column_name = "some_column"]. For tuple structs, all fields must have this annotation.

If a field is another struct which implements QueryableByName, instead of a column, you can annotate that struct with #[diesel(embed)]. Then all fields contained by that inner struct are loaded into the embedded struct.

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 .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.

Attributes

Type attributes

Field attributes

/// # Examples

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

#[derive(QueryableByName, PartialEq, Debug)]
#[table_name = "users"]
struct User {
    id: i32,
    name: String,
}

let first_user = sql_query("SELECT * FROM users ORDER BY id LIMIT 1")
    .get_result(&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, ST> FromSql<ST, DB> for LowercaseString
where
    DB: Backend,
    String: FromSql<ST, DB>,
{
    fn from_sql(bytes: backend::RawValue<DB>) -> deserialize::Result<Self> {
        String::from_sql(bytes)
            .map(|s| LowercaseString(s.to_lowercase()))
    }
}

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

let first_user = sql_query("SELECT * FROM users ORDER BY id LIMIT 1")
    .get_result(&connection)?;
let expected = User { id: 1, name: "sean".into() };
assert_eq!(expected, first_user);

The custom derive generates impls similar to the follownig one

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

impl<DB> QueryableByName<DB> for User
where
    DB: Backend,
    i32: FromSql<diesel::dsl::SqlTypeOf<users::id>, DB>,
    String: FromSql<diesel::dsl::SqlTypeOf<users::name>, DB>,
{
    fn build<'a>(row: &impl NamedRow<'a, DB>) -> deserialize::Result<Self> {
        let id = NamedRow::get::<diesel::dsl::SqlTypeOf<users::id>, _>(row, "id")?;
        let name = NamedRow::get::<diesel::dsl::SqlTypeOf<users::name>, _>(row, "name")?;

        Ok(Self { id, name })
    }
}

let first_user = sql_query("SELECT * FROM users ORDER BY id LIMIT 1")
    .get_result(&connection)?;
let expected = User { id: 1, name: "Sean".into() };
assert_eq!(expected, first_user);