使用Rust/Diesel查询PostgreSQL JSON数组时遇Trait未实现错误
解决Diesel映射PostgreSQL JSON[]到Vec<serde_json::Value>的编译错误
问题原因
Diesel默认未为Array<Json>(对应PostgreSQL的JSON[]类型)到Vec<serde_json::Value>实现Queryable trait,导致编译失败。核心是JSON数组类型的映射规则未匹配正确。
解决步骤
1. 确保依赖配置正确
在Cargo.toml中启用Diesel的postgres和serde_json特性,这是类型映射的基础:
[dependencies] diesel = { version = "2.0.4", features = ["postgres", "serde_json"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0"
2. 方法一:用Diesel的Json包裹类型(简单直接)
修改结构体字段类型为Vec<Json<serde_json::Value>>,Diesel已为该类型实现对应Array<Json>的Queryable:
use diesel::pg::types::json::Json; use serde::{Serialize, Deserialize}; use diesel::Queryable; #[derive(Serialize, Deserialize, Queryable)] struct TestStruct { question_list: Vec<Json<serde_json::Value>>, } // 可选:添加方法直接获取无包裹的Vec<serde_json::Value> impl TestStruct { pub fn get_questions(&self) -> Vec<serde_json::Value> { self.question_list.iter().map(|json_val| json_val.0.clone()).collect() } }
3. 方法二:手动实现Queryable trait(直接映射目标类型)
如果不想用Json包裹类型,可手动实现Queryable完成类型转换:
use diesel::{Queryable, sql_types::{Array, Json}, pg::Pg}; use serde::{Serialize, Deserialize}; use serde_json::Value; #[derive(Serialize, Deserialize)] struct TestStruct { question_list: Vec<Value>, } impl Queryable<Array<Json>, Pg> for TestStruct { type Row = Vec<Json<Value>>; fn build(row: Self::Row) -> diesel::QueryResult<Self> { Ok(Self { question_list: row.into_iter().map(|json_wrap| json_wrap.0).collect(), }) } }
4. 方法三:用Diesel属性自动转换(简化写法)
通过#[diesel(deserialize_as)]属性指定中间转换类型,让Diesel自动完成解包:
use diesel::pg::types::json::Json; use serde::{Serialize, Deserialize}; use diesel::Queryable; #[derive(Serialize, Deserialize, Queryable)] struct TestStruct { #[diesel(deserialize_as = Vec<Json<serde_json::Value>>)] question_list: Vec<serde_json::Value>, }
验证查询代码
你的查询代码无需修改,保持原样即可正常运行:
pub fn min_repro_func() -> Result<TestStruct, diesel::result::Error> { tests::table .select(tests::question_list) .first::<TestStruct>(&mut establish_connection()) }
内容的提问来源于stack exchange,提问作者user3529893
相关产品推荐
相关产品推荐

