【问题标题】:Execute an insert or update using Diesel使用 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() 这样的东西。

【问题讨论】:

    标签: postgresql rust rust-diesel


    【解决方案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

    【讨论】:

      猜你喜欢
      • 2020-10-27
      • 2019-04-23
      • 2011-08-22
      • 2014-05-03
      • 1970-01-01
      • 2014-08-08
      • 2011-04-14
      • 1970-01-01
      • 2014-07-10
      相关资源
      最近更新 更多