Skip to main content

quickhouse

Move tables from PostgreSQL, MySQL, or BigQuery into ClickHouse or BigQuery — fast, in one function call.

quickhouse is a small, typed Python API on top of a native Rust engine. You hand it a source, a destination, and a table name; it figures out the schema, creates the destination table, streams the rows across in parallel, and keeps memory flat the whole way. The heavy lifting never touches Python objects — each database's native wire protocol flows straight into Apache Arrow and out the other side.

import quickhouse

src = quickhouse.Postgres("postgresql://user:pw@localhost:5432/shop")
dst = quickhouse.ClickHouse("http://localhost:8123", database="analytics")

result = quickhouse.sync(src, dst, dest_table="orders",
                         source_table="orders", key=["id"])
print(result)   # rows_read, rows_written, bytes_written, duration_secs, new_watermark

Why quickhouse

  • It's fast. Rows are decoded straight off the wire into Arrow, in Rust — no per-row Python, no intermediate DataFrame. Tables are split into ranges and read in parallel, and decoding overlaps uploading. On a laptop-class box a 1M-row, 20-column full refresh runs at hundreds of thousands of rows per second while peak memory stays flat (under ~180 MB) no matter how much you parallelize. Reproduce it with python benchmarks/bench_transfer.py.

  • It's one function call. sync() replaces the cursor loop, manual batching, retry logic, and CREATE TABLE you'd otherwise write by hand. Defaults handle table creation, type mapping, parallelism, and batching, and a typed stub gives you autocomplete on every argument.

  • It's safe with real, messy data. Full refreshes swap in atomically, so a crash never leaves a half-written table. Incremental syncs are idempotent — safe to re-run or retry. Transient network blips retry automatically. And legacy quirks like MySQL zero-dates or out-of-range timestamps are coerced to NULL with a warning instead of aborting the run.

  • There's nothing to stand up. pip install quickhouse and you're done — no JVM, no Spark cluster, no separate service. It's an ordinary Python dependency that runs wherever your jobs already run: cron, Airflow, Dagster, a Lambda, or a plain script.

Install

pip install quickhouse
pip install "quickhouse[progress]"   # adds a ready-made tqdm progress bar

Prebuilt wheels ship for Python 3.9+ on Linux, macOS (Intel + Apple Silicon), and Windows (x86_64) — no Rust toolchain needed. Building from source is only for development; see CONTRIBUTING.md.

Using it

A fuller call, with the options you'll reach for most:

import quickhouse as qh

src = qh.Postgres("postgresql://user:pw@localhost:5432/shop")
dst = qh.ClickHouse("http://localhost:8123", database="analytics")

qh.sync(
    src, dst,
    dest_table="orders",
    source_table="orders",        # or source_query="SELECT ..."
    mode="incremental",           # or "full"
    watermark="updated_at",       # required for incremental
    key=["id"],                   # dedup key / ORDER BY
    parallelism=8,
    exclude=["internal_notes"],
    rename={"amount": "amt"},
    on_progress=lambda p: print(f"{p.rows_written:,} rows @ {p.rows_per_sec:,.0f}/s"),
)

Sources and destinations

Pick a source and a destination by constructing the matching object — everything else about sync() stays the same:

# sources
qh.Postgres("postgresql://user:pw@host:5432/db")
qh.MySQL("mysql://user:pw@host:3306/db", require_tls=True)
qh.BigQuery("my-gcp-project")                       # source_table="dataset.table"

# destinations
qh.ClickHouse("http://host:8123", database="analytics")
qh.BigQuery("my-gcp-project", dataset_id="analytics")

BigQuery authenticates with a service-account key (credentials_file=...) or Application Default Credentials. As a destination it also takes write_method: the default "insert_all" (simple, proven) or the opt-in "storage_write" (the gRPC Storage Write API — free and higher-throughput).

The DDL knobs (engine, partition_by, order_by, primary_key, key) are interpreted per destination — for ClickHouse they shape the MergeTree DDL; for BigQuery they map to partitioning and clustering. quickhouse creates the table for you (create_if_missing=True by default) with a sensible schema derived from the source.

Full vs. incremental

Full reloads the whole table into a staging table, then swaps it into place atomically — a crash mid-run never leaves the destination partial. For a BigQuery destination that swap runs as a query (a billed scan of the staged data), not a free copy job — BigQuery's copy jobs can silently skip rows still sitting in a table's streaming buffer, so a real query is what keeps this correct rather than just fast.

Incremental tracks a high-water mark (the watermark column) in a small state table in the destination and copies only newer rows. Updated rows are deduplicated on key — via ClickHouse's ReplacingMergeTree, or a MERGE upsert on BigQuery (where key is therefore required). Re-running with no new data does nothing.

For daily syncs that need to catch late-arriving or edited rows, set lookback_seconds to re-scan a trailing window (e.g. 3 * 86400 for the last three days) — the dedup above keeps that overlap from creating duplicates.

Watching progress and diagnosing failures

on_progress is a plain callback you can point at anything; qh.progress_bar() wraps tqdm for a ready-made bar. Every sync() also logs each step to stderr (RUST_LOG=quickhouse_core=debug for the actual SQL).

When something goes wrong, sync() raises a RuntimeError written to be actionable on its own: it names the table involved, and for a bad config or an unmappable column it says exactly what's wrong and how to fix it (e.g. exclude= the column or cast it in a source_query). Underlying database errors are surfaced verbatim rather than wrapped in something generic.

Full parameter list

Parameter Meaning
source_table / source_query Read a whole table, or a custom SELECT (one required)
dest_table Destination table name
mode "full" or "incremental"
watermark Monotonic column for incremental (e.g. updated_at); ignored in full mode
lookback_seconds Re-scan a trailing window of the watermark to catch late/edited rows; 0 disables (default)
key Dedup key (required for BigQuery incremental)
create_if_missing Auto-create the destination table (default True)
engine, order_by, partition_by, primary_key DDL knobs, interpreted per destination
parallelism Concurrent read streams
batch_rows / batch_bytes Per-batch size knobs (rows, or estimated bytes)
max_memory_bytes Hard ceiling on total in-flight memory; decoding blocks when hit (default 512 MiB, 0 = unbounded)
type_overrides Force a destination column type, e.g. {"qty": "Decimal(18, 3)"}
rename, include, exclude Column renames and allow/deny lists
on_progress Progress callback

How types are mapped

quickhouse maps each source type to a sensible destination type automatically: integers to integers, floats to floats, text/JSON/UUID to strings, dates and timestamps across as-is, and booleans preserved. A few deliberate choices worth knowing:

  • Arbitrary-precision decimals (numeric/DECIMAL/NUMERIC) default to Float64, since precision can't be recovered from the type alone. Pin an exact type with type_overrides (e.g. "Decimal(18, 2)").
  • TIME columns transfer as canonical text into a String column (ClickHouse has no time-of-day type).
  • Out-of-range dates (and MySQL zero-dates like 0000-00-00) coerce to NULL with a warning rather than failing the transfer.
  • Nullable source columns stay nullable in the destination.

Arrays and composite (RECORD/STRUCT) types aren't supported yet.

Limitations

  • mTLS (client-certificate auth) isn't supported; server TLS is, including an extra CA file via ca_cert_file=... for providers like AWS RDS.
  • Array / composite types aren't mapped yet.
  • BigQuery as a source reads through a single connection — parallelism becomes a server-side hint rather than true client-side fan-out (a limitation of the underlying crate's read API).
  • No CLI yet, and CDC / custom transforms are future work.

Contributing

Bug reports, new source/type mappings, and PRs are welcome — see CONTRIBUTING.md for build steps, tests, and layout.

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

quickhouse-0.3.1.tar.gz (120.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

quickhouse-0.3.1-cp39-abi3-win_amd64.whl (5.9 MB view details)

Uploaded CPython 3.9+Windows x86-64

quickhouse-0.3.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (6.3 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

quickhouse-0.3.1-cp39-abi3-macosx_11_0_arm64.whl (6.0 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

File details

Details for the file quickhouse-0.3.1.tar.gz.

File metadata

  • Download URL: quickhouse-0.3.1.tar.gz
  • Upload date:
  • Size: 120.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for quickhouse-0.3.1.tar.gz
Algorithm Hash digest
SHA256 860edc19f9853a11771d82c59fe6236b0ab43012fb9658699a4cf140226d7c80
MD5 29cb96e27cdb3d81ba6520645703542d
BLAKE2b-256 19e723aff0cb6c6bf3a838c48c209f5d304d33a9404472507b7c91830db4d313

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickhouse-0.3.1.tar.gz:

Publisher: release.yml on mmirzafahmi/quickhouse

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickhouse-0.3.1-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: quickhouse-0.3.1-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 5.9 MB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for quickhouse-0.3.1-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 0bbd7760094c837e3da66fee96dbb14364bb747e0b05e7ebf716829e6c75b3f2
MD5 109a5148435dfa17d60e22eacec9650b
BLAKE2b-256 20b5133b325f6e6eaa14b432c5094d95c2128d243ef92dfcc35564266a604079

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickhouse-0.3.1-cp39-abi3-win_amd64.whl:

Publisher: release.yml on mmirzafahmi/quickhouse

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickhouse-0.3.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for quickhouse-0.3.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f67db5b4bc8d6be5448770a7d4126124b27ce52d8ea9cdf9b6c3b3e5a0ef4ee8
MD5 ac327712cd8a3970b5b0fbd860f3b4b8
BLAKE2b-256 3118724daf84e83ba9f5566ee1f1ec392bf1d3c77b97d3f951743cb1a2cfb691

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickhouse-0.3.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on mmirzafahmi/quickhouse

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file quickhouse-0.3.1-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for quickhouse-0.3.1-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fa1c43da9112ca2435a4724c664989aac6fdf338f58a8f7f0a564b5f0ac379f7
MD5 bd79592cad9517b3851f04a140de0e7f
BLAKE2b-256 6a6e9bdd617467de96fcfb8672fb7d914f30f5e4dce23555805e40101d5c6fee

See more details on using hashes here.

Provenance

The following attestation bundles were made for quickhouse-0.3.1-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on mmirzafahmi/quickhouse

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.15.0

4 files

0.14.1

4 files

0.14.0

4 files

0.13.0

4 files

0.12.1

4 files

0.12.0

4 files

0.11.0

4 files

0.10.0

4 files

0.9.0

4 files

0.8.0

4 files

0.7.2

4 files

0.7.1

4 files

0.7.0

4 files

0.6.1

4 files

0.6.0

4 files

0.5.0

4 files

0.4.0

4 files

0.3.5

4 files

0.3.4

4 files

0.3.3

4 files

0.3.2

4 files

This release

0.3.1 This release

4 files

0.3.0

4 files

0.2.4

4 files

0.2.3

4 files

0.2.0

4 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page