[英]How to return tokio_postgres ToSql type from closure in Rust?
我如何通过将ToSql
数据作为闭包传递来避免重复自己,告诉 tokio-postgres 哪些数据列,从我的各种结构模型到COPY
/ SELECT
/etc?
例如,理想情况下,我可以传递各种表/列参数,例如:
// see MRE, "copy_in" performs boilerplate to copy binary format in postgres table
copy_in(
&mut client, // the postgres client setup in tokio
"table_name", // meta info about what table/columns to insert
&["col1", "col2", "col3", "col4"],
&vec![Type::INT4, Type::VARCHAR, Type::INT4, Type::INT4],
&rows_of_struct_data, // the vec of data I plan to insert
// then here's the hard part: which fields to extract from each row... (not works)
|m| &[&[&m.id], &[&m.name], &[&m.range_begin, &m.range_end]] as &[&[&(dyn ToSql + Sync)]]
);
tokio_postgres
需要一种用于在复制期间写入二进制数据的类型Vec<&(dyn ToSql + Sync)>
,虽然硬编码什么被push
ed 到 Vec 是有效的,但我很困惑如何传递一个动态决定要push
什么的参数它。
我对此有两个想法,但推荐的方法是什么?
预期
&dyn ToSql + Sync
,找到 trait 对象dyn ToSql
Vec
传递给我的闭包,以便它为每一行推送列数据,但这有几个生命周期问题,例如:对
row
的引用在此处转义异步闭包主体
我不知道如何返回 tokio_postgres &dyn ToSql + Sync 类型。 但是我在下面通过这种方式解决了这个问题。 我正在使用 postgres 的二进制副本插入数据。
桌子:
CREATE TABLE IF NOT EXISTS test (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL
)
为了填充表格,我使用:
use tokio_postgres::types::{Type, ToSql};
use tokio_postgres::binary_copy::BinaryCopyInWriter;
use tokio_postgres::{NoTls, Error};
use futures::{pin_mut};
async fn main() -> Result<(), Error> {
//...
let config = format!("host={} user={} password='{}' dbname={} port={} connect_timeout=10",host, user, passwd, dbname, port);
let (client, connection) = tokio_postgres::connect(&config, NoTls).await?;
tokio::spawn(async move {
if let Err(e) = connection.await {
eprintln!("Connection error: {}", e);
}
});
let data: Vec<(i32,&str)> = vec![(1i32,"hello,"),
(2i32,"world!"),
(3i32,"how"),
(4i32,"are"),
(5i32,"you"),
(6i32,"today?")];
let sink = client
.copy_in("COPY test (id, name) FROM STDIN BINARY")
.await
.unwrap();
let writer = BinaryCopyInWriter::new(sink, &[Type::INT4, Type::VARCHAR]);
pin_mut!(writer);
for i in 0..data.len() {
let (id, name) = data[i];
writer.as_mut().write(&[&id, &name]).await.unwrap();
}
writer.finish().await?;
Ok(())
}
我使用元组来存储数据,然后我解包元组以将数据插入数据库。 依赖项是 tokio-postgres = "0.7.6", tokio = { version = "1.20.0", features = ["full"] } 和 futures = "0.3"。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.