Skip to main content

update

Function update 

Source
pub fn update<T: IntoUpdateTarget>(
    source: T,
) -> UpdateStatement<T::Table, T::WhereClause>
Expand description

Creates an UPDATE statement.

When a table is passed to update, every row in the table will be updated. You can narrow this scope by calling filter on the table before passing it in, which will result in UPDATE your_table SET ... WHERE args_to_filter.

Passing a type which implements Identifiable is the same as passing some_table.find(some_struct.id()).

§Examples

let updated_row = diesel::update(users.filter(id.eq(1)))
    .set(name.eq("James"))
    .get_result(connection);
// On backends that support it, you can call `get_result` instead of `execute`
// to have `RETURNING *` automatically appended to the query. Alternatively, you
// can explicitly return an expression by using the `returning` method before
// getting the result.
assert_eq!(Ok((1, "James".to_string())), updated_row);

To update multiple columns, give set a tuple argument:


let updated_row = diesel::update(users.filter(id.eq(1)))
    .set((name.eq("James"), surname.eq("Bond")))
    .get_result(connection);

assert_eq!(Ok((1, "James".to_string(), "Bond".to_string())), updated_row);

§Batch Update

To update a batch of rows, provide set a slice or a reference to a vector as an argument. You cannot call filter, since a special WHERE clause will be auto-generated instead. The WHERE clause will use the PRIMARY KEY as an identifier to apply the changes. The update struct requires both derive macros AsChangeset and Identifiable.

Batch update using id as the PRIMARY KEY:

table! {
    users {
        id -> Integer,
        name -> VarChar,
        surname -> VarChar,
    }
}

#[derive(Debug, Clone, AsChangeset, Identifiable)]
struct User {
    id: i32,
    name: String,
    surname: String,
}

let users_batch = [
   User { id: 1, name: "James".to_string(), surname: "Bond".to_string() },
   User { id: 6, name: "Mev".to_string(), surname: "Sane".to_string() },
   User { id: 3, name: "Kody".to_string(), surname: "Pineda".to_string() },
   // Previous update of `id = 6` will be overwritten in the database.
   User { id: 6, name: "Mev2".to_string(), surname: "Sane2".to_string() },
];

diesel::update(users::table).set(&users_batch).execute(connection).unwrap();

let updated_rows = users::table.order(users::id).load(connection);

assert_eq!(
    Ok(vec![
        (1, "James".to_string(), "Bond".to_string()), // updated
        (2, "Jim".to_string(), "Brown".to_string()),
        (3, "Kody".to_string(), "Pineda".to_string()), // updated
        (4, "Lea".to_string(), "Kemp".to_string()),
        (5, "Malik".to_string(), "Wu".to_string()),
        (6, "Mev2".to_string(), "Sane2".to_string()) // updated
    ]),
    updated_rows
);

Batch update using (id, name) as the grouped PRIMARY KEY:

table! {
    users (id, name) { // define grouped primary key
        id -> Integer,
        name -> VarChar,
        surname -> VarChar,
    }
}

#[derive(Debug, Clone, AsChangeset, Identifiable)]
#[diesel(primary_key(id, name))] // mandatory: provide grouped primary key
struct User {
    id: i32,
    name: String,
    surname: String,
}

let users_batch = vec![
    User { id: 1, name: "J".to_string(), surname: "Bond".to_string() },
    User { id: 3, name: "K".to_string(), surname: "Pineda".to_string() },
    User { id: 6, name: "Xavier".to_string(), surname: "Mev".to_string() }
];

diesel::update(users::table).set(&users_batch).execute(connection).unwrap();

let updated_rows = users::table.order(users::id).load(connection);

assert_eq!(
    Ok(vec![
        (1, "Sage".to_string(), "Griffin".to_string()), // not updated
        (2, "Jim".to_string(), "Brown".to_string()),
        (3, "Tom".to_string(), "Smith".to_string()), // not updated
        (4, "Lea".to_string(), "Kemp".to_string()),
        (5, "Malik".to_string(), "Wu".to_string()),
        (6, "Xavier".to_string(), "Mev".to_string()) // updated
    ]),
    updated_rows
);