使用 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();
其中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()
这样的东西。
【问题讨论】:
【参考方案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
的值,而&Vec<T>
没有。因此,将其作为参数传递给set
是无效的。
【讨论】:
非常感谢!我花了一段时间才意识到我可以使用excluded
使用 id
- 这有效:diesel::insert_into($table::table).values(&objects).on_conflict($table::id).do_update().set($table::id.eq(excluded($table::id))).execute(conn).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 插入值时,“预期的结构字符串,发现结构模式::my_table::columns::my_column”
Rust Diesel sql_query 带有返回的插入示例