使用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
相关产品推荐
相关产品推荐

