使用 Diesel 执行插入或更新

Execute an insert or update using Diesel

我正在尝试使用 Diesel 和 PostgreSQL 执行插入或更新。

我试过:

diesel::insert_into($table::table).values(&objects).on_conflict($table::id).do_update().set(&objects).execute(conn).unwrap();

其中 objects 是一个 std::vec::Vec<Struct> - 这会导致编译器错误:

^^^ the trait 'diesel::query_builder::AsChangeset' is not implemented for '&std::vec::Vec<Struct>'

查询生成器中有一个 on_conflict_do_nothing(),但我似乎找不到 on_conflict_do_update()on_conflict_do_replace().

之类的东西

Diesel 1.3.3's documentation 已有使用更新插入的示例:

设置冲突的特定值

diesel::insert_into(users)
    .values(&user2)
    .on_conflict(id)
    .do_update()
    .set(name.eq("I DONT KNOW ANYMORE"))
    .execute(&conn);

在冲突时设置 AsChangeset 结构

diesel::insert_into(users)
    .values(&user2)
    .on_conflict(id)
    .do_update()
    .set(&user2)
    .execute(&conn);

使用excluded得到拒绝值

diesel::insert_into(users)
    .values(&vec![user2, user3])
    .on_conflict(id)
    .do_update()
    .set(name.eq(excluded(name)))
    .execute(&conn)

IncompleteDoUpdate::set 采用实现 AsChangeset 的任何值,而 &Vec<T> 没有。因此将它作为参数传递给 set.

是无效的

如果您需要指定如何在发生冲突时更新多个列,set 函数接受一个元组。

例如:

use diesel::pg::upsert::excluded;

let user = User { id: 1, name: "Pascal", age: 18 };
let user2 = User { id: 1, name: "Sean", age: 21 };
let user3 = User { id: 2, name: "Tess", age: 25 };

assert_eq!(Ok(1), diesel::insert_into(users).values(&user).execute(&conn));

let insert_count = diesel::insert_into(users)
    .values(&vec![user2, user3])
    .on_conflict(id)
    .do_update()
    .set((
        name.eq(excluded(name)),
        age.eq(excluded(age)),
    ))
    .execute(&conn);

参见:https://docs.diesel.rs/diesel/fn.update.html#examples