在github上有,一个异步连接clickhouse的库,值得一看。
具体用法:
extern crate tokio;
use std::{env, error::Error};
use clickhouse_rs::{row, types::Block, Pool};
use futures_util::StreamExt;
async fn execute(database_url: String) -> Result<(), Box<dyn Error>> {
env::set_var("RUST_LOG", "clickhouse_rs=debug");
env_logger::init();
//建表,在default库下面,创建payment表
let ddl = r"
CREATE TABLE IF NOT EXISTS payment (
customer_id UInt32,
amount UInt32,
account_name Nullable(FixedString(3))
) Engine=Memory";
// insert数据
let mut block = Block::with_capacity(5);
block.push(row! { customer_id: 1_u32, amount: 2_u32, account_name: Some("foo") })?;
block.push(row! { customer_id: 3_u32, amount: 4_u32, account_name: None::<&str> })?;
block.push(row! { customer_id: 5_u32, amount: 6_u32, account_name: None::<&str> })?;
block.push(row! { customer_id: 7_u32, amount: 8_u32, account_name: None::<&str> })?;
block.push(row! { customer_id: 9_u32, amount: 10_u32, account_name: Some("bar") })?;
let pool = Pool::new(database_url);
let mut client = pool.get_handle().await?;
client.execute(ddl).await?;
client.insert("payment", block).await?;
// 异步查询数据
let mut stream = client.query("SELECT * FROM payment").stream();
while let Some(row) = stream.next().await {
let row = row?;
let id: u32 = row.get("customer_id")?;
let amount: u32 = row.get("amount")?;
let name: Option<&str> = row.get("account_name")?;
println!("Found payment {}: {} {:?}", id, amount, name);
}
Ok(())
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let database_url = env::var("DATABASE_URL").unwrap_or_else(|_| {
"tcp://localhost:9000?compression=lz4&ping_timeout=2s&retry_timeout=3s".into()
});
execute(database_url).await
}
在clickhouse-client端查询结果:
SELECT *
FROM default.payment
Query id: 108a3571-d3fc-48de-8dce-5596c8ce5dd1
┌─customer_id─┬─amount─┬─account_name─┐
│ 1 │ 2 │ foo │
│ 3 │ 4 │ ᴺᵁᴸᴸ │
│ 5 │ 6 │ ᴺᵁᴸᴸ │
│ 7 │ 8 │ ᴺᵁᴸᴸ │
│ 9 │ 10 │ bar │
└─────────────┴────────┴──────────────┘
5 rows in set. Elapsed: 0.002 sec.