You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rust Diesel中用单条更新语句反转布尔字段值?

在Rust Diesel中用单条语句切换SQLite待办事项的完成状态

你已经通过Diesel定义了todos表:

diesel::table! {
    todos (id) {
        id -> Integer,
        parent_id -> Nullable<Integer>,
        title -> Text,
        done -> Bool,
    }
}

对应的模型结构体:

#[derive(Queryable, QueryableByName, AsChangeset)]
#[diesel(table_name = todos)]
pub struct Todo {
    pub id: i32,
    pub parent_id: Option<i32>,
    pub title: String,
    pub done: bool
}

想要实现单条更新语句切换done字段的布尔状态(无需前置查询),对应的原生SQL是UPDATE todos SET done = NOT done WHERE id = ?,之前的写法报错是因为没找对Diesel中处理列表达式取反的方式,正确实现如下:

正确代码实现

需要使用Diesel提供的not函数(来自diesel::dsl模块)来对列表达式进行取反操作:

use diesel::dsl::not;

fn toggle_todo_done(conn: &mut SqliteConnection, id: i32) -> Todo {
    diesel::update(todos.find(id))
        .set(done.eq(not(done)))
        .get_result::<Todo>(conn)
        .unwrap()
}

为什么之前的写法报错?

  • 使用!done时,你是把Diesel的columns::done列表达式当成了普通Rust布尔值,但columns::done的类型并没有实现std::ops::Not trait,所以无法直接用!运算符取反。
  • 使用done.ne(done)是生成了“不等于自身”的表达式,逻辑上永远为false,而且该表达式类型不符合AsChangeset的要求,因此报错。

效果说明

上述代码会生成你预期的原生SQL语句,直接在数据库层面完成状态切换,无需先查询待办事项再更新,完全满足你的需求。

内容的提问来源于stack exchange,提问作者Simone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 22:07:27