diesel

Function insert_into

Source
pub fn insert_into<T: Table>(target: T) -> IncompleteInsertStatement<T>
Expand description

Creates an INSERT statement for the target table.

You may add data by calling values() or default_values() as shown in the examples.

Backends that support the RETURNING clause, such as PostgreSQL, can return the inserted rows by calling .get_results instead of .execute.

§Examples

let rows_inserted = diesel::insert_into(users)
    .values(&name.eq("Sean"))
    .execute(connection);

assert_eq!(Ok(1), rows_inserted);

let new_users = vec![
    name.eq("Tess"),
    name.eq("Jim"),
];

let rows_inserted = diesel::insert_into(users)
    .values(&new_users)
    .execute(connection);

assert_eq!(Ok(2), rows_inserted);

§Using a tuple for values

let new_user = (id.eq(1), name.eq("Sean"));
let rows_inserted = diesel::insert_into(users)
    .values(&new_user)
    .execute(connection);

assert_eq!(Ok(1), rows_inserted);

let new_users = vec![
    (id.eq(2), name.eq("Tess")),
    (id.eq(3), name.eq("Jim")),
];

let rows_inserted = diesel::insert_into(users)
    .values(&new_users)
    .execute(connection);

assert_eq!(Ok(2), rows_inserted);

§Using struct for values

#[derive(Insertable)]
#[diesel(table_name = users)]
struct NewUser<'a> {
    name: &'a str,
}

// Insert one record at a time

let new_user = NewUser { name: "Ruby Rhod" };

diesel::insert_into(users)
    .values(&new_user)
    .execute(connection)
    .unwrap();

// Insert many records

let new_users = vec![
    NewUser { name: "Leeloo Multipass" },
    NewUser { name: "Korben Dallas" },
];

let inserted_names = diesel::insert_into(users)
    .values(&new_users)
    .execute(connection)
    .unwrap();

§Inserting default value for a column

You can use Option<T> to allow a column to be set to the default value when needed.

When the field is set to None, diesel inserts the default value on supported databases. When the field is set to Some(..), diesel inserts the given value.

The column color in brands table is NOT NULL DEFAULT 'Green'.

#[derive(Insertable)]
#[diesel(table_name = brands)]
struct NewBrand {
    color: Option<String>,
}

// Insert `Red`
let new_brand = NewBrand { color: Some("Red".into()) };

diesel::insert_into(brands)
    .values(&new_brand)
    .execute(connection)
    .unwrap();

// Insert the default color
let new_brand = NewBrand { color: None };

diesel::insert_into(brands)
    .values(&new_brand)
    .execute(connection)
    .unwrap();

§Inserting default value for a nullable column

The column accent in brands table is DEFAULT 'Green'. It is a nullable column.

You can use Option<Option<T>> in this case.

When the field is set to None, diesel inserts the default value on supported databases. When the field is set to Some(None), diesel inserts NULL. When the field is set to Some(Some(..)) diesel inserts the given value.

#[derive(Insertable)]
#[diesel(table_name = brands)]
struct NewBrand {
    accent: Option<Option<String>>,
}

// Insert `Red`
let new_brand = NewBrand { accent: Some(Some("Red".into())) };

diesel::insert_into(brands)
    .values(&new_brand)
    .execute(connection)
    .unwrap();

// Insert the default accent
let new_brand = NewBrand { accent: None };

diesel::insert_into(brands)
    .values(&new_brand)
    .execute(connection)
    .unwrap();

// Insert `NULL`
let new_brand = NewBrand { accent: Some(None) };

diesel::insert_into(brands)
    .values(&new_brand)
    .execute(connection)
    .unwrap();

§Insert from select

When inserting from a select statement, the column list can be specified with .into_columns. (See also SelectStatement::insert_into, which generally reads better for select statements)

let new_posts = users::table
    .select((
        users::name.concat("'s First Post"),
        users::id,
    ));
diesel::insert_into(posts::table)
    .values(new_posts)
    .into_columns((posts::title, posts::user_id))
    .execute(conn)?;

let inserted_posts = posts::table
    .select(posts::title)
    .load::<String>(conn)?;
let expected = vec!["Sean's First Post", "Tess's First Post"];
assert_eq!(expected, inserted_posts);

§With return value

let inserted_names = diesel::insert_into(users)
    .values(&vec![
        name.eq("Diva Plavalaguna"),
        name.eq("Father Vito Cornelius"),
    ])
    .returning(name)
    .get_results(connection);
assert_eq!(Ok(vec!["Diva Plavalaguna".to_string(), "Father Vito Cornelius".to_string()]), inserted_names);