Releases

SeaORM Integrates Apache Arrow and ClickHouse for Zero-SQL OLAP Pipelines

SeaORM now pipes data into ClickHouse with zero hand-written SQL, using Apache Arrow as the bridge between Rust entity models and columnar storage.

Nina Kowalski2 min read
Published
Listen to this article0:00 min
Share this article:
SeaORM Integrates Apache Arrow and ClickHouse for Zero-SQL OLAP Pipelines
Source: www.sea-ql.org

The Sea-QL team dropped a technical post on March 8, 2026 showing how SeaORM can drive a full OLAP/ETL pipeline into ClickHouse without a single hand-written SQL statement. The mechanism runs through Apache Arrow: derive DDL from your entity, create the table, stream batches in. That's the entire workflow.

The centerpiece is a new `arrow_schema` attribute added to the `#[sea_orm(...)]` annotation on an entity. Annotating a struct with `#[sea_orm(table_name = "measurement", arrow_schema)]` tells SeaORM to derive the Arrow schema at compile time, which SeaORM then uses to generate the corresponding ClickHouse DDL automatically. A `voltage` column typed `Decimal` and annotated with `#[sea_orm(column_type = "Decimal(Some((38, 4)))")]` in the Rust struct becomes `Decimal(38, 4)` in ClickHouse; a `ChronoDateTime` field becomes `DateTime64(6)`; a `LowCardinality(String)` device column lands exactly as you'd expect. The generated DDL for the `sensor_readings` example uses `ReplacingMergeTree()` with a primary key on `(recorded_at, device)`, a sensible default for time-series sensor data where late-arriving duplicates need deduplication.

On the insertion side, three methods carry the load. `measurement::Entity::arrow_schema()` returns the compile-time schema. `measurement::ActiveModel::to_arrow(&models, &schema)?` takes a slice of `ActiveModel` instances and converts them into an Arrow `RecordBatch`, with the `?` making the fallibility explicit. From there, `client.insert_arrow("measurement", &schema).await?` opens an insert handle, `insert.write_batch(&batch).await?` sends the data, and `insert.end().await?` finalizes the transaction. The transport is HTTP, which keeps the ClickHouse client dependency straightforward.

AI-generated illustration
AI-generated illustration

The appeal here is the compile-time guarantee. The Arrow schema isn't derived at runtime from reflection or a config file; it's baked in during compilation, which means type mismatches between the Rust model and the ClickHouse table surface as build errors rather than runtime panics in a production pipeline. For anyone who's chased down a silent column type mismatch in an ETL job at 2 a.m., that's a meaningful shift.

All the examples the post references are available as runnable code in the Sea-QL repository. The Sea-QL team is also promoting their Rustacean Sticker Pack alongside the release, featuring premium water-resistant vinyl with a matte finish, available through SeaQL's community channels for those who want to show some crab allegiance while their pipelines hum along.

Know something we missed? Have a correction or additional information?

Submit a Tip
Your Topic
Today's stories
Updated daily by AI

Name any topic. Get daily articles.

You pick the subject, AI does the rest.

Start Now - Free

Ready in 2 minutes

Discussion

More Rust Programming News