True upserts in an append-only world: ReplacingMergeTree and FINAL.
Day 07 of the WClickHouse Open-Source Engineering Series.
You don't need slow SQL UPDATE statements to maintain current state in ClickHouse. WClickHouse harnesses ReplacingMergeTree for lightning-fast upserts.
The Pain Points We Faced
- Attempting expensive UPDATE mutations on billions of ClickHouse rows
- Dealing with duplicate state updates in streaming event pipelines
- Slow analytical queries returning outdated record revisions
The Implementation
# Configure ReplacingMergeTree with version column for upserts db = WClickHouse( OrderStateModel, db_config, engine="ReplacingMergeTree(version) ORDER BY order_id" ) # Append updated version: ClickHouse deduplicates on merge! db.insert(OrderStateModel(order_id=101, status="shipped", version=2)) # Query guaranteed latest state: latest = db.execute_query("SELECT * FROM orderstatemodel FINAL WHERE order_id = 101") Why This Architecture Wins
- ReplacingMergeTree: Declare replacing engines directly in WClickHouse initialization.
- FINAL Modifier Support: Query true current state with instant background deduplication.
- Zero Mutation Locks: Writes remain fast appends while ClickHouse cleans duplicates in background.
Verification & Status
Tested and verified against live ClickHouse server instances with 95%+ test coverage. Built for Python 3.9 through 3.14 with Apache Arrow and Pydantic v2.
![Real Time Operating Systems — Ch.12: RTOS Case Studies [EN]](https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9f8b1u4hxrwc1uq4gfe2.png)