在 Rust 中使用 Tokio-postgres 将多个值插入到 Postgres

问题描述 投票:0回答:2

我正在使用下面的代码使用 tokio-postgres 插入到 Postgres 数据库,有没有更好的选择:

let members = &[obj] //obj is a struct
let mut params = Vec::<&(dyn ToSql + Sync)>::new();
let mut i = 1;
let mut qry:String = "insert into tablename(id,userid,usertype) values".to_string();
for column in members{
    if(i ==1){
        qry = format!("{} (${},${},${})",qry,i,i+1,i+2);
    }else{
        qry = format!("{}, (${},${},${})",qry,i,i+1,i+2);

    }
    params.push(&column.id);
    params.push(&column.userid);
    params.push(&column.usertype);
    i = i+3;
               
}
println!("qry : {}",qry);
let result = p.execute(&qry, &params[..]).await; //p is the pool manager
postgresql rust multiple-insert tokio-postgres
2个回答
7
投票

否:

您可以通过使用迭代器稍微改进它:

use itertools::Itertools; // For tuples() and format_with()

let params: Vec<_> = members
    .iter()
    .flat_map(|row| [&row.id as &(dyn ToSql + Sync), &row.userid, &row.usertype])
    .collect();
let query = format!(
    "insert into tablename(id, userid, usertype) values {}",
    (0..params.len())
        .tuples()
        .format_with(", ", |(i, j, k), f| {
            f(&format_args!("(${i}, ${j}, ${k})"))
        }),
);

但是我真的不认为这样更好。


0
投票

您可以将插入数据拆分为每列一个数组,然后像这样传递它:

let result = p.execute("
    INSERT INTO tablename(id, userid, usertype)
    SELECT unnest($1::integer[]), unnest($2::varchar[]), unnest($3::my_usertype_enum[])
",
    &[&ids, &userids, &usertypes]).await;

优点是您可以准备语句,因为它是固定查询。缺点我不知道。

© www.soinside.com 2019 - 2024. All rights reserved.