clickhouse-connect v1.10.0
Rust codec performance
- NumPy and Pandas queries no longer require PyArrow. This covers buffered and streamed results and
query(..., use_numpy=True). Strings use Arrow conversion when available and Rust object conversion otherwise. Invalid UTF-8 keeps its hex rendering. Explicit Arrow output and Arrow storage still require PyArrow. - Supported numeric, Boolean, BFloat16, Interval, date, timestamp, and time columns now convert directly from decoded buffers. Selected nullable, Array, and LowCardinality shapes also use this path. Existing output dtypes stay unchanged, apart from the nanosecond correction described below.
- Large response chunks now feed the decoder in bounded slices, reducing temporary copies and peak memory for large NumPy, Pandas, and Python results.
Client improvements
- DB-API connections and cursors now support
withblocks. They close on normal and exceptional exit. Connection contexts don't manage transactions thuscommit()androllback()are still no-ops. - Async Arrow inserts move DataFrame conversion and Arrow encoding to a dedicated client worker, reducing event-loop stalls. #1054
- Large async external-data uploads use bounded writes to reduce event-loop stalls during TLS encryption. Upload payloads are replayable for eligible retries. #1057
Query and insert fixes
QueryResult.result_rowsworks after materializingresult_columns, including async queries withcolumn_oriented=True.- Dynamic shared-storage values and JSON paths beyond
max_dynamic_typesdecode supported compound and scalar values to Python objects. Nullable defaults and typed JSON null paths work, and DataFrame results retain the decoded objects. #1070 - Internal
DESCRIBE TABLErequests get their own query ID. Inserts retain the caller's ID, avoidingQUERY_WITH_SAME_ID_IS_ALREADY_RUNNINGerrors. #1066 - After a remote close or HTTP 429/503/504, SQL execution retries only recognized reads. Writes, DDL, mutations,
SET,USE, andCHECK TABLEaren't replayed. This also applies through DB-API and SQLAlchemy. Read retries and insert API retries are still available. #1079
Streaming and temporal fixes
- Synchronous Native response cleanup waits for active reads and drains partially consumed HTTP chunks through the same parser. Early Rust stream closure drains the response before releasing its iterator, avoiding premature closure and subsequent
SESSION_IS_LOCKEDerrors. - Rust cleanup releases each response source once, handles closure during read-ahead startup, and releases decoder workers after cancelled pending reads.
- Async Rust stream cleanup finishes before cancellation is re-raised.
- Rust NumPy and Pandas results preserve nanoseconds in nullable scalar
DateTime64(9)columns, includingSimpleAggregateFunctionaliases. Unsupported scalar precisions now fail consistently. - Nullable
SimpleAggregateFunctionaliases ofTime64return correct durations andNaTfor NULL values.
SQLAlchemy and Alembic fixes
- Importing the dialect preserves another provider's
clickhouse://registration. Generated schema metadata and Alembic revisions useclickhousedb_*options so copies and migrations work with both drivers installed. #1074 GROUP BYuses aliases only for matching top-level expressions selected by the query. Unselected and nested expressions render in full. #1062Nullable()andLowCardinality()preserve the wrapped type in their return annotations. #1033- Alembic accepts reflected
AggregateFunctionstate versions when metadata omits the version, including nested types. Explicit versions still detect changes; legacy unversioned states match explicit version0.
Installation
pip install clickhouse-connectFor the experimental Rust codec:
pip install "clickhouse-connect[rust]"The Rust extra requires clickhouse-connect-core>=0.2.1,<0.3. The driver checks both binding and column-buffer APIs and reports upgrade guidance for older wheels.
clickhouse-connect-core` releases independently of the driver. To pick up compatible codec fixes without changing your driver version:
pip install --upgrade "clickhouse-connect-core>=0.2.1,<0.3"
The NumPy/Pandas improvements in 1.10.0 also require upgrading clickhouse-connect so a core-only upgrade won't enable them.
For users upgrading both:
pip install --upgrade "clickhouse-connect[rust]" "clickhouse-connect-core>=0.2.1,<0.3"
Upgrade notes
- In mixed installs with
clickhouse-sqlalchemy, useclickhousedb://orclickhousedb+connect://. Rename ClickHouse Connect schema options toclickhousedb_*and register custom defaults underclickhousedb. Generated metadata uses this prefix. Read engine and Dictionary options through their canonical keys, including in cc-only installs; public reflection dictionaries retain their existingclickhouse_*keys. - Type checkers infer
list[String]for[Nullable(String)]. Annotate mixed type collections aslist[ChSqlaType]. - Rust NumPy object columns for nullable scalar
DateTime64(9)now contain UTCnumpy.datetime64cells instead of Pythondatetimecells. SQL NULL is stillNone. Pandas output preserves nanoseconds. All-null block object inference is unchanged. Usequery_dfto retain named timezone metadata. - Insert API retries provide at-least-once delivery and can duplicate rows without server deduplication. Check the outcome before retrying an ambiguous SQL write in your application.