You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust Diesel中如何不绑定具体后端为带泛型的结构体实现Trait

解决方案

完全可以不绑定具体数据库后端实现该trait,你遇到的错误是由两个问题共同导致的:

  • 错误中出现Pg的原因:diesel 会根据 Cargo.toml 中启用的数据库后端 feature 生成默认的 schema 约束,你开启了 postgres feature,所以编译器推导时会默认尝试匹配 Pg 后端,和你声明的泛型参数产生冲突。
  • 你的泛型约束不足:仅声明了后端支持 Bool 类型的 SQL 表达,缺少了 Rust 类型和 SQL 类型的序列化/反序列化约束。

修正后的代码

use diesel::select;
use crate::authenticator::AuthDB;
use crate::diesel::dsl::exists;
use crate::diesel::prelude::*;
use crate::schema::users;

// 可以移除多余的泛型参数B,直接通过Connection的关联类型Backend获取后端类型
pub struct DB<C>
where
    C: diesel::Connection,
{
    conn: C,
}

impl<C> AuthDB for DB<C>
where
    C: diesel::Connection,
    // 约束1:后端支持Bool、Text两种SQL类型
    C::Backend: diesel::sql_types::HasSqlType<diesel::sql_types::Bool> + diesel::sql_types::HasSqlType<diesel::sql_types::Text>,
    // 约束2:Rust bool类型可以从后端的Bool SQL类型反序列化
    bool: diesel::deserialize::FromSql<diesel::sql_types::Bool, C::Backend>,
    // 约束3:Rust String类型可以序列化为后端的Text SQL类型
    String: diesel::serialize::ToSql<diesel::sql_types::Text, C::Backend>,
{
    fn exists_by_id_and_password(
        &self,
        id: String,
        password: String,
    ) -> Result<bool, crate::error::Error> {
        Ok(select(exists(
            users::dsl::users.filter(
                users::dsl::username
                    .eq(id)
                    .and(users::dsl::password.eq(password)),
            ),
        ))
        .get_result::<bool>(&self.conn)?)
    }
}

补充说明

只要你不在表结构中使用某款数据库特有的字段类型,该实现可以兼容所有 diesel 支持的数据库后端,后续切换后端只需要修改 Cargo.toml 中的 feature 配置、实例化DB时传入对应后端的连接实例即可,不需要修改业务逻辑代码。

内容的提问来源于stack exchange,提问作者wangjun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 22:15:07