使用 Diesel 执行插入或更新

Posted

技术标签:

【中文标题】使用 Diesel 执行插入或更新【英文标题】:Execute an insert or update using Diesel 【发布时间】:2018-05-17 11:40:48 【问题描述】:

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

我试过了:

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

其中objectsstd::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() 这样的东西。

【问题讨论】:

【参考方案1】:

Diesel 1.3.3's documentation 已经有使用 upsert 的示例:

为冲突设置具体值

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 的值,而&amp;Vec&lt;T&gt; 没有。因此,将其作为参数传递给set 是无效的。

【讨论】:

非常感谢!我花了一段时间才意识到我可以使用 excluded 使用 id - 这有效:diesel::insert_into($table::table).values(&amp;objects).on_confl‌​ict($table::id).do_u‌​pdate().set($table::‌​id.eq(excluded($tabl‌​e::id))).execute(con‌​n).unwrap 嘿,你知道如何使它适用于 sqlite 吗?【参考方案2】:

如果您需要指定如何在冲突时更新多个列,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

【讨论】:

以上是关于使用 Diesel 执行插入或更新的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Diesel 执行“更新自”?

尝试使用 Diesel 插入值时,“预期的结构字符串,发现结构模式::my_table::columns::my_column”

Rust Diesel sql_query 带有返回的插入示例

了解 Diesel 中的特征绑定错误

如何使用 Diesel 和 SQLite 获取新创建值的 id?

如何使用 Diesel 和 SQLite 获取新创建值的 id?