clickhouse-connect is a ClickHouse driver built around HTTP and data frames
Python driver/sqlalchemy/superset connectors
At a glance
- What is it?
- clickhouse-connect talks to ClickHouse over the HTTP interface rather than the native protocol, and that choice is what makes it work with pandas, NumPy, PyArrow, Polars and Superset with no conversion layer. It also ships a lightweight SQLAlchemy dialect, an async client and Alembic support, with the limits of the ORM path stated plainly.
- Who is it for?
- Adopt clickhouse-connect when you are pulling ClickHouse data into pandas, Arrow or Polars, when you need a Superset connection, or when you want Alembic migrations against ClickHouse without giving up SQLAlchemy Core.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 7 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why HTTP is the design decision
clickhouse-connect is described as a high performance core database driver for connecting ClickHouse to Python, Pandas and Superset, and the design decision is stated up front: it uses the ClickHouse HTTP interface for maximum compatibility.
That choice explains the rest of the library. The HTTP interface is the same one the ClickHouse web interface and the HTTP client use, so it works through proxies, through load balancers and in environments where the native TCP protocol is blocked or awkward. The cost is that some ClickHouse capabilities that depend on the native protocol are not reachable, and the driver adds its own layer on top to recover what it can.
The result types are the other half of the design. The library returns Pandas DataFrames, both numpy and arrow backed, which requires pandas 2.0 or later, plus NumPy arrays, PyArrow tables and Polars DataFrames. So the query result comes back in the shape the data library expects, rather than as a list of tuples you have to convert yourself, and the conversion happens in the driver where the column types are still known.
Two integrations sit alongside the data frames. There is a Superset connector, and there is SQLAlchemy Core support, described as covering select, joins and lightweight deletes with a limited feature set.
There is also an experimental path that is worth knowing about. A chDB backend is available for running queries against an embedded in-process engine, used with `get_client(interface='chdb')` and installed with `pip install clickhouse-connect[chdb]`. That is a different product in the same package, a local ClickHouse engine inside your process rather than a remote server, and the README labels it experimental.
The project is Python, Apache 2.0 licensed, with the releases v1.11.0 from 2026-10-16, v1.10.1 from 2026-10-14 and v1.10.0 from 2026-10-07, and the last push on 2026-10-16.
Installing, and the 1.0 boundary
The install is one command:
pip install clickhouse-connectand ClickHouse Connect requires Python 3.10 or higher.
The upgrade note is the part to read carefully. The 1.0 release includes breaking changes, and if you are upgrading from a 0.15.x or earlier release, the README points to MIGRATION.md for a guide to the changes and their replacements.
That is worth pausing on, because the release cadence is fast. Three releases in nine days, v1.10.0 on 2026-10-07, v1.10.1 on 2026-10-14 and v1.11.0 on 2026-10-16. A project shipping that often will break assumptions, and the 0.x to 1.x boundary is exactly where a driver changes how it names things.
The versioning of the two pieces is separate, and the README is explicit about it. The `clickhouse-connect` package and the optional `clickhouse-connect-core` Rust binding are versioned independently, and the PyPI badges show their latest published versions. So you can be on driver 1.11 with a core binding from an earlier line, and the GitHub releases track only the driver.
The release notes live in two changelogs, the driver changelog in `CHANGELOG.md` at the root and the core binding changelog at `rust/ch-core-py/CHANGELOG.md`. Keeping both in view is necessary when you are diagnosing a behaviour difference, since a fix can live in either.
The core binding is the Rust part, in the `rust/` directory of the repository, and it is optional rather than required, which is what keeps the pure Python install path working.
The SQLAlchemy dialect and its stated limits
The dialect is described as a lightweight SQLAlchemy dialect implementation focused on compatibility with Superset and SQLAlchemy Core, and the README is unusually precise about what that means.
The synchronous dialect supports SQLAlchemy 1.4 and 2.x. The 1.4 support is maintained because Apache Superset currently requires `sqlalchemy>=1.4,<2`, which is a dependency fact rather than a preference, and it means your dialect version is constrained by your Superset version rather than by your own choice.
The URL schemes are `clickhousedb://` for synchronous connections, and `clickhousedb+connect://` is the alternative. There is also a coexistence detail: when `clickhouse-sqlalchemy` is also installed, importing this dialect preserves its `clickhouse://` registration, so the two do not collide.
The supported feature list is longer than you would expect for something called lightweight. Basic query execution via SQLAlchemy Core, SELECT queries with JOINs including ClickHouse-specific strictness, USING and GLOBAL modifiers, ARRAY JOIN in single and multi-column form, FINAL, SAMPLE, compound selects and materialized CTEs. The VALUES table function syntax. Lightweight DELETE statements. And Alembic schema migrations with autogenerate, upgrade and downgrade, plus ClickHouse engine support.
A few features need SQLAlchemy 2.x specifically. `Values.cte()` requires 2.0.42 or later, and certain literal rendering behaviours also require 2.x. Everything else, including what Superset uses, works on both.
The ORM limits are the important part to read before choosing it. Basic ORM usage works for insert-heavy, read-focused workloads: declarative model definitions, CREATE TABLE, `session.add()`, `bulk_save_objects()` and read queries all function correctly. But full ORM support is not provided. UPDATE compilation, foreign key and relationship reflection, autoincrement with RETURNING, and cascade operations are not implemented. The dialect is best suited for SQLAlchemy Core usage and Superset connectivity.
That is a coherent position rather than an apology. ClickHouse is not a row-store with a transaction model, so the ORM features that depend on row identity and cascading writes have no meaning there, and pretending otherwise would be worse than saying so.
Async SQLAlchemy and the Alembic route
Async SQLAlchemy usage is available with SQLAlchemy 2.0.44 and later. The extra is `clickhouse-connect[sqlalchemy-async]`, the URL scheme is `clickhousedb+async://`, and you create the engine with `create_async_engine()`.
Three details in that sentence matter. Results are buffered, server-side cursors are not supported, and during shutdown you should always await the async engine's `dispose()` method instead of calling `engine.sync_engine.dispose()`.
The buffering is the direct consequence of the driver design. A result set that is buffered in the client cannot be streamed, so a query returning more rows than fits in memory is a memory problem rather than a streaming problem. That is fine for the analytics-sized queries this driver targets, and it is wrong for a scan of a very large table where you want the server to send rows lazily.
Alembic support is the other half of the SQLAlchemy story, and it is the part that makes the dialect usable for schema management rather than only for queries. Alembic migrations are supported including autogeneration of migration scripts from SQLAlchemy metadata, and ClickHouse table engines such as MergeTree and ReplacingMergeTree, along with dictionaries, are preserved through the migration lifecycle.
The supported operations are create and drop table, add, alter, drop and rename column, type and nullability changes, defaults, comments, and ClickHouse-specific features like IF EXISTS guards, column placement with AFTER, and operation-level `clickhouse_settings` on column add, alter or drop.
The install and setup for the async case:
For the async dialect the extras are combined, installing `clickhouse-connect[alembic,sqlalchemy-async]`, followed by `alembic init -t async alembic`, and then replacing the generated `alembic/env.py` with the checked-in async Alembic environment at `examples/alembic_async/env.py`. The README tells you to keep the generated `script_location = %(here)s/alembic`, or to update it if you chose a different migration directory. The example includes the ClickHouse Alembic hooks and options, runs online migrations through `AsyncConnection.run_sync()`, and compiles offline migrations without creating an engine.
There is also a worked example document in the dialect directory covering setup, autogeneration, upgrades, downgrades and manual migration operations.
Native async client and the build
The native asyncio client is separate from the SQLAlchemy async dialect, and it is the lighter of the two.
pip install clickhouse-connect[async]Then you create a client with `clickhouse_connect.get_async_client()`, with the `run_async` example in the examples directory for the details. The implementation uses aiohttp, which is why the async dependency is an extra: the synchronous path does not need it.
The build system tells you how the package is put together. The build backend is setuptools with `setuptools>=77.0.3` and `cython>=3.1,<4` as requirements, and the presence of Cython means parts of the driver are compiled rather than interpreted. The `setup.py` shows the two environment variables that control that, `CLICKHOUSE_CONNECT_SKIP_CYTHON` and `CLICKHOUSE_CONNECT_REQUIRE_C`, and it raises a RuntimeError if both are set to 1, since they are mutually exclusive.
The CI configuration builds wheels with cibuildwheel, skipping `cp39-*` and `pp39-*`, which matches the Python 3.10 floor.
The linting and typing setup is detailed. Ruff targets py310 with a line length of 140, and it excludes the generated driver C sources, the `clickhouse_connect/driverc` directory. Mypy checks the `clickhouse_connect` package with a python_version of 3.10, and it has two override groups: one for dependencies that may be absent or lack type stubs, including the compiled Cython modules, and one that lists modules which do not yet pass type checking with a reference to issue 692 and a note to remove entries as modules are annotated. That comment tells you the type checking is improving incrementally rather than being all or nothing.
The test configuration runs pytest with a `test.env` file for environment, a session scope for the asyncio fixture loop and `-n 4` for parallel execution.
Superset, and where this driver fits
The Superset integration has a history that explains its current shape. ClickHouse Connect is fully integrated with Apache Superset, and previous versions used a dynamically loaded Superset Engine Spec. As of Superset v2.1.0 the engine spec was incorporated into the main Apache Superset project and removed from clickhouse-connect in v0.6.0. If you have issues connecting to earlier versions of Superset, the README says to use clickhouse-connect v0.5.25.
So the driver and Superset are versioned against each other in practice, and the pinned combination for an old Superset is a specific old driver release.
When creating a Superset data source, you either use the provided connection dialog or a SQLAlchemy DSN in the form `clickhousedb://{username}:{password}@{host}:{port}`.
The alternative approach is worth naming, because it comes down to protocol. A driver that speaks ClickHouse's native TCP protocol can use features of the server that the HTTP interface does not expose, and it avoids the HTTP layer entirely, but it loses the portability that HTTP gives you: the same code stops working behind a proxy or in an environment that only allows HTTP traffic. For a Superset deployment, which is a long-running server in a corporate network, HTTP is usually the more practical choice, which is why the HTTP-first driver is a reasonable default.
There is also the chDB route inside the same package, an embedded in-process engine, which removes the network hop entirely at the cost of the experimental label and the resources of running the engine inside your process.
For the wider documentation, the README says the documentation has moved to the ClickHouse docs site under the Python integrations page, which tells you where to look for anything the README does not cover.
Editorial conclusion
Adopt clickhouse-connect when you are pulling ClickHouse data into pandas, Arrow or Polars, when you need a Superset connection, or when you want Alembic migrations against ClickHouse without giving up SQLAlchemy Core. Do not adopt it if you need full SQLAlchemy ORM semantics, since UPDATE compilation, foreign key reflection, autoincrement with RETURNING and cascades are not implemented, and treat the 1.0 boundary as real, since the README points upgrading 0.15.x and earlier users to MIGRATION.md. Verify first that you are on Python 3.10 or newer, that your Superset version matches the dialect, since older Superset releases need clickhouse-connect v0.5.25, and that the version you pin matches the release you read, with v1.11.0 published on 2026-10-16.
Frequently asked questions
What does clickhouse-connect do and how does it connect?
It is a high performance core database driver for connecting ClickHouse to Python, Pandas and Superset, and it uses the ClickHouse HTTP interface for maximum compatibility. Results come back as Pandas DataFrames with numpy or arrow backing, NumPy arrays, PyArrow tables or Polars DataFrames.
How do I install clickhouse-connect?
With `pip install clickhouse-connect`, and Python 3.10 or higher is required. There are optional extras for the async client, the Alembic support, the async SQLAlchemy dialect and the experimental chDB backend, each installed with a bracketed extra such as `pip install clickhouse-connect[async]`.
Does clickhouse-connect support the full SQLAlchemy ORM?
No. Basic ORM usage works for insert-heavy, read-focused workloads, with declarative models, CREATE TABLE, session.add(), bulk_save_objects() and read queries functioning correctly. UPDATE compilation, foreign key and relationship reflection, autoincrement with RETURNING and cascade operations are not implemented, and the dialect is best suited to SQLAlchemy Core usage and Superset connectivity.
How do I use clickhouse-connect with Superset?
Use the provided connection dialog, or a SQLAlchemy DSN of the form `clickhousedb://{username}:{password}@{host}:{port}`. Note that as of Superset v2.1.0 the engine spec moved into the Superset project itself and was removed from clickhouse-connect in v0.6.0, so for earlier Superset versions the README recommends clickhouse-connect v0.5.25.
What changed in clickhouse-connect 1.0?
The 1.0 release includes breaking changes, and the README points users upgrading from a 0.15.x or earlier release to MIGRATION.md for a guide to the changes and their replacements. The driver and the optional Rust core binding are versioned independently, with separate changelogs.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/clickhouse-clickhouse-connect)Was this useful?