Derive Macro diesel_derives::Insertable
source · #[derive(Insertable)]
{
// Attributes available to this derive:
#[diesel]
#[table_name]
#[column_name]
}
Expand description
Implements Insertable
To implement Insertable
this derive needs to know the corresponding table
type. By default, it uses the snake_case
type name with an added s
from the current scope.
It is possible to change this default by using #[diesel(table_name = something)]
.
If table_name
attribute is given multiple times, impls for each table are generated.
If a field name of your
struct differs from the name of the corresponding column,
you can annotate the field with #[diesel(column_name = some_column_name)]
.
Your struct can also contain fields which implement Insertable
. This is
useful when you want to have one field map to more than one column (for
example, an enum that maps to a label and a value column). Add
#[diesel(embed)]
to any such fields.
To provide custom serialization behavior for a field, you can use
#[diesel(serialize_as = SomeType)]
. If this attribute is present, Diesel
will call .into
on the corresponding field and serialize the instance of SomeType
,
rather than the actual field on your struct. This can be used to add custom behavior for a
single field, or use types that are otherwise unsupported by Diesel.
Using #[diesel(serialize_as)]
is incompatible with #[diesel(embed)]
.
Normally, Diesel produces two implementations of the Insertable
trait for your
struct using this derive: one for an owned version and one for a borrowed version.
Using #[diesel(serialize_as)]
implies a conversion using .into
which consumes the underlying value.
Hence, once you use #[diesel(serialize_as)]
, Diesel can no longer insert borrowed
versions of your struct.
Attributes
Optional container attributes
#[diesel(table_name = path::to::table)]
, specifies a path to the table this type is insertable into. The path is relative to the current module. If this attribute is not used, the type name converted tosnake_case
with an addeds
is used as table name#[diesel(treat_none_as_default_value = false)]
, specifies thatNone
values should be converted toNULL
values on the SQL side instead of being treated asDEFAULT
value primitive. Note: This option may control if your query is stored in the prepared statement cache or not*
Optional field attributes
#[diesel(column_name = some_column_name)]
, overrides the column the current field maps tosome_column_name
. By default, the field name is used as column name#[diesel(embed)]
, specifies that the current field maps not only to a single database field, but is a struct that implementsInsertable
#[diesel(serialize_as = SomeType)]
, instead of serializing the actual field type, Diesel will convert the field intoSomeType
using.into
and serialize that instead. By default, this derive will serialize directly using the actual field type.
Examples
If we want to customize the serialization during insert, we can use #[diesel(serialize_as)]
.
#[derive(Debug, FromSqlRow, AsExpression)]
#[diesel(sql_type = sql_types::Text)]
struct UppercaseString(pub String);
impl Into<UppercaseString> for String {
fn into(self) -> UppercaseString {
UppercaseString(self.to_uppercase())
}
}
impl<DB> ToSql<sql_types::Text, DB> for UppercaseString
where
DB: Backend,
String: ToSql<sql_types::Text, DB>,
{
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
self.0.to_sql(out)
}
}
#[derive(Insertable, PartialEq, Debug)]
#[diesel(table_name = users)]
struct InsertableUser {
id: i32,
#[diesel(serialize_as = UppercaseString)]
name: String,
}
let user = InsertableUser {
id: 1,
name: "thomas".to_string(),
};
diesel::insert_into(users)
.values(user)
.execute(connection)
.unwrap();
assert_eq!(
Ok("THOMAS".to_string()),
users.select(name).first(connection)
);