Rust Diesel使用sql_query插入并返回ID出现trait未实现错误如何解决
报错原因
sql_query 返回的结果是按列名做类型映射的,Rust 原生类型 i32 未实现 QueryableByName<Pg> trait,无法直接匹配SQL返回的demoid列。
解决方案
方案1:自定义接收结构体(适配当前手写SQL的写法)
首先定义一个和返回列结构匹配的结构体,添加QueryableByName派生宏:
use diesel::prelude::*; // 字段名必须和SQL返回的列名完全一致 #[derive(QueryableByName, Debug)] struct DemoIdResult { demoid: i32, }
修改查询代码,先接收结构体再提取ID:
let results: Vec<DemoIdResult> = sql_query("insert into demo (demoname, description, demovalue) values (?, ?, 2) returning demoid") .bind::<Text, _>("Demo1") .bind::<Text, _>("Demo2") .get_results(&conn) .unwrap(); // 提取得到i32类型的ID列表 let demo_id: Vec<i32> = results.into_iter().map(|r| r.demoid).collect();
方案2:改用Diesel原生ORM语法(更推荐)
如果你的项目已经生成了demo表的schema代码,直接用内置插入语法即可,不需要手写SQL,也不会有类型映射问题:
// 导入你的表结构,路径根据你的项目调整 use crate::schema::demo; let demo_id: i32 = diesel::insert_into(demo::table) .values(( demo::demoname.eq("Demo1"), demo::description.eq("Demo2"), demo::demovalue.eq(2), )) .returning(demo::demoid) .get_result(&conn) .unwrap(); // 如果是批量插入需要返回多个ID,把get_result替换为get_results::<i32>即可
简易hack方案(不推荐生产环境用)
如果不想定义结构体,可以把返回列别名为数字下标,直接用元组接收:
let demo_id: Vec<(i32,)> = sql_query("insert into demo (demoname, description, demovalue) values (?, ?, 2) returning demoid as \"0\"") .bind::<Text, _>("Demo1") .bind::<Text, _>("Demo2") .get_results(&conn) .unwrap();
内容的提问来源于stack exchange,提问作者Gonzalo
相关产品推荐
相关产品推荐

