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

如何封装diesel_async的get_results方法?

如何在泛型函数中调用diesel_async的get_results方法?

修复后的完整代码

use diesel::{debug_query, pg::Pg, BoolExpressionMethods, ExpressionMethods, QueryDsl, Queryable, Identifiable};
use diesel_async::{RunQueryDsl, AsyncPgConnection, AsyncConnection, methods::LoadQuery};
use serde::{Serialize, Deserialize};

type DB = diesel::pg::Pg;

diesel::table! {
    foo (id) {
        id -> Int4,
        label -> Nullable<Text>,
    }
}

#[derive(Queryable, Debug, Serialize, Deserialize, Identifiable)]
#[diesel(primary_key(id))]
#[diesel(table_name = foo)]
pub struct Foo {
    pub id: i32,
    pub label: Option<String>,
}

pub async fn get_results_wrapped<'query, 'conn, QueryType, ResultItemType>(
    qry: &'query QueryType,
    conn: &'conn mut AsyncPgConnection
) -> Result<Vec<ResultItemType>, diesel_async::error::Error>
where
    &'query QueryType: LoadQuery<'query, AsyncPgConnection, ResultItemType>,
    ResultItemType: Send + 'query,
    QueryType: Sync + 'query,
{
    qry.get_results(conn).await
}

#[tokio::main]
async fn main() {
    let mut conn = AsyncPgConnection::establish(&std::env::var("DATABASE_URL").unwrap()).await.unwrap();

    let qry = foo::table.filter(foo::id.eq(foo::id));

    // 原正常调用逻辑
    let query_str = debug_query::<DB,_>(&qry).to_string();
    let results = qry.get_results::<Foo>(&mut conn).await.unwrap();

    // 修复后的调用
    let results: Vec<Foo> = get_results_wrapped(&qry, &mut conn).await.unwrap();
}

关键改动说明

  1. 调整返回值类型:将函数返回值从Vec<ResultItemType>改为Result<Vec<ResultItemType>, diesel_async::error::Error>,既保留错误处理能力,也解决了原代码中Vec类型无unwrap方法的错误。

  2. 修正泛型约束:

    • 约束&'query QueryType: LoadQuery<'query, AsyncPgConnection, ResultItemType>:LoadQuery trait通常为查询的引用类型实现,而非查询本身,这是原代码约束不匹配的核心原因。
    • 添加QueryType: Sync + 'query和ResultItemType: Send + 'query:满足异步运行时的线程安全要求,解决Send/Sync相关的trait绑定错误。
  3. 简化调用逻辑:移除get_results后的显式类型标注,泛型参数可通过上下文自动推导,减少冗余代码。

Cargo.toml依赖(保持不变)

diesel = { version = "2.2.6", features = ["chrono", "postgres", "uuid", "serde_json"] }
diesel-async = { version ="0.5.2", features = [ "deadpool", "postgres"] }
tokio = { version = "1.40", features = ["full"] }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 09:40:18