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

使用Rust Diesel操作SQLite时获取插入行的问题求助

解决Rust Diesel操作SQLite获取插入行ID的问题

一、修复sql_query获取last_insert_rowid的错误

你的错误核心在于load方法需要明确的类型映射,SQLite的last_insert_rowid()返回单列结果,Diesel要求用元组类型接收(即使只有一列,也要用元组表示完整的行),而非直接使用i32或BigInt。

修改后的代码:

let conn = &mut get_connection();

let new_post = NewPost{title, body};
// 执行插入并处理错误
diesel::insert_into(posts::table)
    .values(new_post)
    .execute(conn)
    .expect("插入数据失败");

// 获取最后插入行的ID
let result: Vec<(i64,)> = diesel::sql_query("SELECT last_insert_rowid()")
    .load(conn)
    .expect("获取插入ID失败");

// 提取ID值
let inserted_id = result[0].0;

解释:

  • (i64,)表示一行包含一个i64类型的列,匹配SQLite中ROWID的64位整数类型
  • 从返回的Vec中取出第一个元素,再提取元组的第一个值即为插入的ID

二、更优雅的Diesel原生实现(推荐)

如果你的SQLite版本≥3.35.0(支持RETURNING子句),可以直接用Diesel的returning方法,无需手动执行SQL查询:

let conn = &mut get_connection();

let new_post = NewPost{title, body};
// 返回完整插入行
let inserted_post: Post = diesel::insert_into(posts::table)
    .values(new_post)
    .returning(posts::all_columns)
    .get_result(conn)
    .expect("插入并获取行失败");

// 仅返回ID
let inserted_id: i64 = diesel::insert_into(posts::table)
    .values(new_post)
    .returning(posts::id)
    .get_result(conn)
    .expect("获取插入ID失败");

为什么之前get_result无效?

  • 可能是SQLite版本过低(低于3.35.0),不支持RETURNING子句,导致Diesel的get_result报错
  • 需确保Post结构体与数据库表的字段类型、顺序完全匹配

三、关于table.order(id.desc()).first(&conn)的问题

SQLite的主键默认会自动生成ROWID(即使未显式设置AUTOINCREMENT),只要id列是INTEGER类型的主键,这个方法就能生效。但该方式存在并发风险,高并发场景下可能获取到其他请求插入的ID,可靠性不如last_insert_rowid()或RETURNING。

四、依赖优化

你的Cargo.toml中包含了MySQL相关的mysqlclient-sys依赖,若仅使用SQLite,可移除该依赖以减少编译负担:

[dependencies]
diesel = { version = "2.0.0", features = ["sqlite"] }
dotenv = "0.15.0"
serde = "1.0.140"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 16:01:02