ClickHouse
Native insert. Merge uses `ReplacingMergeTree` keyed by `dedup_sort`.
Every destination receives the same layout; see the tables Ingest creates.
Setup
Ingest connects over the HTTPS interface and needs a user that can create and write tables in one database.
Create a user
CREATE USER ingest IDENTIFIED BY 'a-long-random-password';
GRANT CREATE DATABASE, CREATE TABLE, INSERT, SELECT, ALTER, DROP ON your_db.* TO ingest;
Each of those is used: CREATE TABLE per resource, INSERT for rows, SELECT to read back the
_ingest_* state tables, ALTER when your source adds a column, and DROP for atomic replace, which
loads into a new table and swaps, so a reader never sees a half-written one. Omitting DROP leaves
replace-mode resources failing while append works, which is a confusing place to end up.
On ClickHouse Cloud the user you were given at signup already holds these; a dedicated user is still worth creating so revoking Ingest does not mean rotating your own login.
Reachable, and on the HTTPS port
Ingest egresses from a public address and has no route into your network. Use the HTTPS endpoint
(8443 on Cloud, 8123 unencrypted for self-hosted; prefer TLS), and allow Ingest's egress address in
any IP access list. ClickHouse Cloud denies all addresses by default, so a new service refuses the
connection test until that list is edited.
What to paste
HTTP URL (the full https://host:8443) and the Password.
Then test it
Test connection creates a scratch schema and a table, writes a few rows through the same load path a real run uses, reads them back to check the count is exactly right, round-trips pipeline state, and drops the lot. Creating a database and writing to it are separate grants, so both are exercised.
Staging
needs_staging: none. Staging always happens in the destination's own cloud and region; data
does not take a detour through ours.
Conformance
Every adapter passes the same suite before it ships: create a table with every canonical type, append
100k rows, atomic replace, merge (latest dedup_sort wins; child tables delete-then-insert by root
id), schema evolution, NULL-key rejection, package replay without duplicates, state and schema
round-trip, row-count read-back, identifier edge cases, double-underscored table names (__quarantine, child tables), and rollback on a
mid-load failure.