Skip to content

ClickHouse: Rust (`clickhouse` crate)

Typed rows over the ClickHouse HTTP interface (RowBinary format).

# CLICKHOUSE_URL
https://clickhouse.internal:8443
https://warehouse.internal:8443
# CLICKHOUSE_USER / CLICKHOUSE_PASSWORD
ClickHouse user
MachWarehouse user

For https URLs enable one of the crate’s TLS features (for example rustls-tls) in Cargo.toml.

Terminal window
cargo run

Libraries: clickhouse 0.15.3, tokio 1.54.1, serde 1.0.229.

The program as it is kept and tested in the Mach Database Warehouse repository; highlighted lines read the connection setting.

src/main.rs
//! Prints revenue per country with the `clickhouse` crate over the ClickHouse
//! HTTP interface. Plain ClickHouse client code: nothing here knows about
//! MachWarehouse. Load the table first with any other example.
use clickhouse::{Client, Row};
use serde::Deserialize;
#[derive(Debug, Row, Deserialize)]
struct CountryRevenue {
country: String,
events: u64,
revenue: f64,
}
#[tokio::main]
async fn main() -> Result<(), clickhouse::error::Error> {
let env = |k: &str, d: &str| std::env::var(k).unwrap_or_else(|_| d.to_owned());
let client = Client::default()
.with_url(env("CLICKHOUSE_URL", "http://localhost:8123"))
.with_user(env("CLICKHOUSE_USER", "default"))
.with_password(env("CLICKHOUSE_PASSWORD", ""))
.with_database(env("CLICKHOUSE_DATABASE", "default"));
let rows = client
.query(
"SELECT country, count() AS events, toFloat64(sum(revenue)) AS revenue \
FROM events GROUP BY country ORDER BY revenue DESC",
)
.fetch_all::<CountryRevenue>()
.await?;
for r in rows {
println!("{}\t{}\t{:.2}", r.country, r.events, r.revenue);
}
Ok(())
}
Cargo.toml
[package]
name = "clickhouse-rust-example"
version = "0.1.0"
edition = "2024"
publish = false
# Standalone: not a member of the MachWarehouse workspace.
[workspace]
[dependencies]
clickhouse = "0.15.3"
serde = { version = "1.0.229", features = ["derive"] }
tokio = { version = "1.54.1", features = ["macros", "rt-multi-thread"] }