如何不使用Backend::RawValue实现Diesel自定义SQL类型?
在Diesel v2+中实现无废弃API的自定义UUID类型(适配SQLite与Wasm)
要在Diesel v2+中实现基于Binary类型的自定义UUID封装,同时避开Backend::RawValue的废弃API,核心是利用FromSql trait自身的关联类型RawValue,而非直接访问后端的RawValue。以下是调整后的可维护实现:
修改后的完整代码
use uuid::Uuid; use diesel::{ backend::Backend, deserialize::{self, FromSql, FromSqlRow}, expression::AsExpression, serialize, sql_types::Binary, }; #[derive(Debug, Clone, Copy, AsExpression, FromSqlRow)] #[diesel(sql_type = Binary)] pub struct UUID { id: Uuid, } impl UUID { pub fn new(id: Uuid) -> Self { Self { id } } // 可选:添加获取内部Uuid的方法,方便业务使用 pub fn as_uuid(&self) -> &Uuid { &self.id } } // 序列化逻辑:直接委托给Uuid的实现 impl<B: Backend> serialize::ToSql<Binary, B> for UUID where Uuid: serialize::ToSql<Binary, B>, { fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, B>) -> serialize::Result { Uuid::to_sql(&self.id, out) } } // 反序列化逻辑:使用FromSql的关联RawValue,避开Backend::RawValue的废弃路径 impl<B: Backend> deserialize::FromSql<Binary, B> for UUID where Uuid: deserialize::FromSql<Binary, B>, { type RawValue = <Uuid as deserialize::FromSql<Binary, B>>::RawValue; fn from_sql(raw: Self::RawValue<'_>) -> deserialize::Result<Self> { Uuid::from_sql(raw).map(UUID::new) } }
关键修改说明
- 替换RawValue来源:将原代码中直接使用的
<B as Backend>::RawValue改为FromSqltrait的关联类型Self::RawValue,完全遵循Diesel v2+的新API设计,避免依赖废弃路径。 - 显式声明RawValue关联类型:通过
type RawValue = <Uuid as deserialize::FromSql<Binary, B>>::RawValue;,直接复用Uuid实现中定义的RawValue类型,确保类型一致性。 - 简化代码结构:去掉冗余的 trait 限定语法,直接使用
Uuid::to_sql和Uuid::from_sql,提升代码可读性。
适配Wasm与SQLite的额外注意事项
- 确保
uuidcrate启用v7特性(Cargo.toml中添加uuid = { version = "1.0", features = ["v7", "serde"] }),支持UUIDv7生成。 - 对于Wasm环境,需确保Diesel的SQLite后端依赖正确配置:启用
diesel_sqlite的bundled特性,或者使用适配Wasm的SQLite绑定。 - 测试时可直接使用
UUID::new(Uuid::now_v7())生成符合要求的UUIDv7值,存入SQLite的BLOB类型列(对应Diesel的Binarysql类型)。
内容的提问来源于stack exchange,提问作者AntonMiles
相关产品推荐
相关产品推荐

