clickhouse-connect 1.2.0
This release adds opt-in server-side bind parameters for the SQLAlchemy dialect, a token_provider client option for refreshable access tokens, and custom HTTP headers on client creation. It also ships a batch of SQLAlchemy reflection and type fixes along with several correctness fixes in query parameter handling and DSN parsing.
⚠️ Upgrade note: literal % in a DSN
The dsn passed to create_client / create_async_client now percent-decodes the username, password, and database. This lets you supply credentials that contain reserved characters in URL-encoded form, so pass%20word decodes to pass word.
If your DSN contains a literal %, you must now escape it as %25. A DSN credential like pa%ss will otherwise be misread. This is the one behavior change in this release that can affect existing setups, so check your connection strings before upgrading. A DSN with a username and no password now also sends an empty password rather than the literal string None. Closes #713.
Highlights
New features
- Server-side bind parameters for SQLAlchemy. Opt in with
create_engine(url, server_side_params=True). The dialect then emits ClickHouse native{name:Type}/{name:Array(Type)}placeholders instead of client-side string interpolation. Off by default. Closes #735. token_providerclient option. Sync and async. It accepts a callable that returns an access token string. The callable is invoked once for the initial token and again to fetch a fresh token whenever the server rejects the current one on an authentication failure, retrying the request once. Mutually exclusive withaccess_tokenandusername/password.- Custom HTTP
headers. A newheadersoption oncreate_client/create_async_clientattaches custom headers to every request, including the initialization queries sent during client creation. Useful for HTTP gateways that require auth headers such as Cloudflare Access service tokens.
Bug fixes
- A
datetimebound to a server-side{name:DateTime64(...)}placeholder now keeps its sub-second precision instead of being truncated to seconds. The declared parameter type drives this, so no_64name suffix or manualDT64Paramwrapper is needed, and it applies throughArrayandTuplehints. PlainDateTimebinds are unchanged. Closes #739. bytes/bytearrayquery parameters now render as ClickHouse string literals, each byte as\xHH, instead of the Python repr. This fixes inserts intoFixedString/Stringcolumns through the SQLAlchemy dialect. Closes #777.- Strip
--line comments that have no following space when classifying queries, so a DDL with a leading--sql-style comment is routed as a command instead of raisingStreamFailureError. Closes #499.
SQLAlchemy improvements
- Reflection is now implemented on the dialect itself, so
MetaData.reflect()andInspector.get_multi_columns()work. - UDT-based types such as
UUID,IPv4/IPv6,JSON,Nested, geometry types, andAggregateFunctionnow return concretepython_typeclasses instead ofNone, matching SQLAlchemy'sTypeEngine.python_typecontract. Arraynow subclassessqlalchemy.types.ARRAYand exposesitem_type.
Installation
pip install clickhouse-connect