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

使用bb8_postgres传递整数参数报错:expected &(dyn ToSql + Sync), found i32

问题

使用bb8_postgres操作PostgreSQL时,执行查询传递整数参数出现错误:expected &(dyn ToSql + Sync), found i32
错误代码行:

let rows = client.query("SELECT value FROM test WHERE id = $1;", &[id]).await.unwrap();

完整代码:

use std::time::{Duration, Instant};
use bb8::Pool;
use bb8_postgres::PostgresConnectionManager;
use tokio_postgres::NoTls;

async fn test_postgresql() -> (Duration, Duration) {

    let pg_mgr = PostgresConnectionManager::new_from_stringlike(
        "postgresql://postgres:postgres@localhost:5432/my_db",
        NoTls,
    )
    .unwrap();

    let pool = match Pool::builder().build(pg_mgr).await {
        Ok(pool) => pool,
        Err(e) => panic!("bb8 error {e}"),
    };

    println!("Writing");
    let write_duration = test_postgresql_write(&pool).await;
    println!("Reading");
    let read_duration = test_postgresql_read(&pool).await;

    (write_duration, read_duration)
}


async fn test_postgresql_write(pool: &bb8::Pool<bb8_postgres::PostgresConnectionManager<NoTls>>) -> Duration {
    let client = pool.get().await.unwrap();

    client.batch_execute("DROP TABLE IF EXISTS test;").await.unwrap();
    client.batch_execute("CREATE TABLE test (id SERIAL PRIMARY KEY, value TEXT);").await.unwrap();

    let start_time = Instant::now();

    for i in 0..1000 {
        let value = format!("value_{}", i);
        client.execute("INSERT INTO test (value) VALUES ($1);", &[&value]).await.unwrap();
    }

    start_time.elapsed()
}


async fn test_postgresql_read(pool: &bb8::Pool<bb8_postgres::PostgresConnectionManager<NoTls>>) -> Duration {
    let client = pool.get().await.unwrap();

    let start_time = Instant::now();

    for i in 0..1000 {
        let id = i + 1;
        // Line with Error
        let rows = client.query("SELECT value FROM test WHERE id = $1;", &[id]).await.unwrap();
        let value: &str = rows[0].get(0);
        assert_eq!(value, format!("value_{}", i));
    }

    start_time.elapsed()
}

如何将整数转换为查询所需的正确类型?

解决方案

错误核心是client.query要求参数为实现ToSql + Sync trait的引用类型,直接传递i32值不符合类型要求。有两种修复方式:

  • 传递整数引用(推荐):与写操作中传递&value的写法保持一致,将参数数组改为&[&id]:

    let rows = client.query("SELECT value FROM test WHERE id = $1;", &[&id]).await.unwrap();
    
  • 显式匹配PostgreSQL整数类型:若需要明确对应Postgres的SERIAL(本质是int4)类型,可使用postgres_types中的Int4类型包裹后传引用:

    use postgres_types::types::Int4;
    // ...
    let rows = client.query("SELECT value FROM test WHERE id = $1;", &[&Int4(id)]).await.unwrap();
    

第一种方式简洁且符合现有代码风格,是最优选择。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 07:23:17