使用tokio_postgres查询PostgreSQL返回Row结构而非预期数据怎么解决?
问题原因
tokio_postgres的query方法返回结果为Vec<tokio_postgres::Row>类型,Row是底层存储查询结果的结构,本身包含字段元数据和实际值,直接打印Debug格式只会输出结构定义,不会自动提取字段值,也不会直接序列化为JSON格式,需要你手动把Row中的值映射到自定义结构体后再做序列化。
解决步骤
1. 补充依赖
先在Cargo.toml中添加如下依赖,用于结构体映射和JSON序列化:
[dependencies] tokio = { version = "1.0", features = ["full"] } tokio-postgres = "0.7" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" # 可选:如果要自动实现Row到结构体的映射,添加下面的依赖 tokio-postgres-derive = "0.4"
2. 定义User结构体并实现映射
方法1:手动映射(无需额外派生依赖)
直接遍历查询返回的Row列表,逐个提取字段值即可:
mod domain; mod types; use tokio_postgres::NoTls; use types::AsyncResult; use serde::Serialize; // 定义用户结构体,派生Serialize用于JSON序列化 #[derive(Debug, Serialize)] struct User { id: i32, name: String, } #[tokio::main] async fn main() -> AsyncResult<()> { let (client, connection) = tokio_postgres::connect( "postgres://test_user:secret_password@localhost/test_database", NoTls, ) .await?; tokio::spawn(async move { if let Err(error) = connection.await { eprintln!("连接错误: {}", error); } }); let rows = client.query("SELECT id, name FROM users", &[]).await?; // 把Row数组转成User数组 let mut users = Vec::with_capacity(rows.len()); for row in rows { users.push(User { id: row.get("id"), name: row.get("name"), }); } // 序列化为格式化JSON输出 let users_json = serde_json::to_string_pretty(&users)?; println!("{}", users_json); Ok(()) }
方法2:使用FromRow派生自动映射
如果表字段较多,手动映射效率太低,可以用tokio-postgres-derive提供的FromRow派生宏自动实现映射逻辑:
// 导入FromRow派生宏 use tokio_postgres_derive::FromRow; use serde::Serialize; #[derive(Debug, Serialize, FromRow)] struct User { id: i32, name: String, } // 查询完成后直接批量转换即可 let users: Vec<User> = rows.into_iter() .map(|row| row.try_into().expect("字段映射失败")) .collect();
运行修改后的代码即可输出你预期的JSON格式结果。
内容的提问来源于stack exchange,提问作者miravelardo
相关产品推荐
相关产品推荐

