使用Rust Diesel读写PostgreSQL字节数组时读取失败的问题排查
问题描述
我正在尝试用Rust Diesel从PostgreSQL数据库读写字节数组,相关代码及报错如下:
数据库Schema定义
table! { data_table (id) { id -> Int4, data_name -> Nullable<Text>, data_bytes -> Nullable<Bytea>, } }
模型代码
#[derive(Queryable)] pub struct DataItem { pub id: i32, pub data_name: String, pub data_bytes: Vec<u8>, } use super::schema::data_table; #[derive(Insertable)] #[table_name="data_table"] pub struct NewDataItem { pub data_name: String, pub data_bytes: Vec<u8>, }
测试代码
写入测试可正常运行,但读取测试报错:
#[test] fn read_data() { let conn = establish_connection(); let results = data_table.filter(data_name.eq("test")) .limit(5) .load::<DataItem>(&conn) .expect("Error reading data"); }
错误信息
error[E0277]: the trait bound `*const str: FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not satisfied --> src/tests.rs:36:10 | 36 | .load::<DataItem>(&conn) | ^^^^ the trait `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Text>, _>` is not implemented for `*const str`
error[E0277]: the trait bound `*const [u8]: FromSql<diesel::sql_types::Nullable<diesel::sql_types::Binary>, _>` is not satisfied --> src/tests.rs:36:10 | 36 | .load::<DataItem>(&conn) | ^^^^ the trait `FromSql<diesel::sql_types::Nullable<diesel::sql_types::Binary>, _>` is not implemented for `*const [u8]`
解决方法
报错核心原因是数据库Schema中定义的data_name和data_bytes是可空(Nullable)类型,但模型里对应的字段用了非空的String和Vec<u8>,Diesel无法自动完成这种类型转换。你可以通过以下两种方式解决:
1. 让模型字段匹配数据库的可空定义
把DataItem中的对应字段改成Option<T>类型,明确表示该字段可能为空:
#[derive(Queryable)] pub struct DataItem { pub id: i32, pub data_name: Option<String>, // 改为可空类型 pub data_bytes: Option<Vec<u8>>, // 改为可空类型 }
2. 调整Schema移除可空约束(如果业务允许)
如果你确定data_name和data_bytes不会存储空值,可以直接修改Schema去掉Nullable标记,这样原模型的非空类型就能正常工作:
table! { data_table (id) { id -> Int4, data_name -> Text, // 移除Nullable data_bytes -> Bytea, // 移除Nullable } }
额外修正:读取测试的字段引用
原读取测试里的data_name.eq("test")存在字段引用不明确的问题,需要改成Schema导出的字段,避免编译错误:
#[test] fn read_data() { let conn = establish_connection(); let results = data_table::table .filter(data_table::data_name.eq("test")) // 明确引用schema中的字段 .limit(5) .load::<DataItem>(&conn) .expect("Error reading data"); }
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

