使用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
相关产品推荐
相关产品推荐

