chDB is an in-process OLAP SQL Engine ๐ powered by ClickHouse
21
stars
3,815
commits
C++
primary language
Sep 8, 2026
updated
chdb-core is the foundational engine of the chDB ecosystem โ an in-process SQL OLAP Engine powered by ClickHouse 1
chdb-core (this repo) is the engine; chDB is a higher-level pandas-compatible DataStore API built on top of it (see the diagram below). The engine itself ships as five distribution artifacts โ three Python wheels (same import chdb, differing only by build flags) and two JavaScript/WASM packages:
| Artifact | How to get it | Target / runtime | Best for |
|---|---|---|---|
| chdb-core | PyPI โ pip install chdb-core | Python 3.9+ (Linux/macOS) | Default full build โ everything included |
| chdb-core-lite | PyPI โ pip install chdb-core-lite | Python 3.9+ (Linux/macOS) | Slimmer build that trims less-common features (e.g. external connectors like MySQL/Kafka) |
| chdb-core (free-threaded) | GitHub release assets | Free-threaded Python 3.14t (no GIL) | Running chDB without the GIL |
| chdb-wasm | npm โ npm install chdb-wasm | Browsers & Node (WebAssembly) | Running the full engine in the browser or Node |
| chdb-cloudflare | npm โ npm install chdb-cloudflare | Cloudflare Workers | A slimmer build for Cloudflare Workers |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ chDB (pip install chdb) โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ โ DataStore: pandas-like lazy API โ โ โ โ QueryPlanner / dual-engine exec โ โ โ โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโ โ โ โ โ โ โโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโ โ โ โ chdb-core (pip install chdb-core) โ โ โ โ C++ ClickHouse Engine โ โ โ โ Session / Connection / DB-API โ โ โ โ query() / UDF / Stream โ โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
chdb-core provides everything you need to run SQL queries with ClickHouse performance โ no server required. If you want a higher-level pandas-compatible DataFrame API, install chDB instead.
Currently, chdb-core supports Python 3.9+ on macOS and Linux (x86_64 and ARM64).
pip install chdb-core
import chdb
result = chdb.query("SELECT version()", "Pretty")
print(result)
The simplest way to run SQL โ no session or connection needed:
import chdb
# Basic query with CSV output (default)
result = chdb.query("SELECT 1, 'hello'")
print(result)
# Pandas DataFrame output
df = chdb.query("SELECT number, number * 2 AS double FROM numbers(10)", "DataFrame")
print(df)
# Parameterized queries
df = chdb.query(
"SELECT toDate({base_date:String}) + number AS date "
"FROM numbers({total_days:UInt64}) "
"LIMIT {items_per_page:UInt64}",
"DataFrame",
params={"base_date": "2025-01-01", "total_days": 10, "items_per_page": 5},
)
print(df)
import chdb
res = chdb.query('SELECT * FROM file("data.parquet", Parquet)', "JSON")
print(res)
res = chdb.query('SELECT * FROM file("data.csv", CSV)', "CSV")
print(res)
# Query result statistics
print(f"SQL read {res.rows_read()} rows, {res.bytes_read()} bytes, "
f"storage read {res.storage_rows_read()} rows, {res.storage_bytes_read()} bytes, "
f"elapsed {res.elapsed()} seconds")
# Pandas DataFrame output
chdb.query('SELECT * FROM file("data.parquet", Parquet)', "Dataframe")
Connection-based API for cursor-style interaction, supporting both in-memory and file-based databases:
import chdb
conn = chdb.connect(":memory:")
cur = conn.cursor()
cur.execute("CREATE TABLE test (id UInt32, name String) ENGINE = Memory")
cur.execute("INSERT INTO test VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Charlie')")
cur.execute("SELECT * FROM test ORDER BY id")
print(cur.fetchone()) # (1, 'Alice')
print(cur.fetchmany(2)) # ((2, 'Bob'), (3, 'Charlie'))
print(cur.column_names()) # ['id', 'name']
print(cur.column_types()) # ['UInt32', 'String']
# Use the cursor as an iterator
cur.execute("SELECT number FROM system.numbers LIMIT 3")
for row in cur:
print(row)
# Always close resources when done
cur.close()
conn.close()
For more details, see examples/connect.py.
# File-based persistent database
conn = chdb.connect("mydata.db")
conn.query("CREATE TABLE IF NOT EXISTS logs (ts DateTime, msg String) ENGINE = MergeTree ORDER BY ts")
conn.query("INSERT INTO logs VALUES (now(), 'started')")
result = conn.query("SELECT * FROM logs", "Pretty")
print(result)
conn.close()
Sessions provide a higher-level API with automatic resource management:
from chdb import session as chs
sess = chs.Session()
sess.query("CREATE DATABASE IF NOT EXISTS db_xxx ENGINE = Atomic")
sess.query("CREATE TABLE IF NOT EXISTS db_xxx.log_table (x String, y Int) ENGINE = Log")
sess.query("INSERT INTO db_xxx.log_table VALUES ('a', 1), ('b', 3), ('c', 2), ('d', 5)")
sess.query("CREATE VIEW db_xxx.view_xxx AS SELECT * FROM db_xxx.log_table LIMIT 4")
print(sess.query("SELECT * FROM db_xxx.view_xxx", "Pretty"))
see also: test_stateful.py.
Process large datasets with constant memory usage through chunked streaming:
from chdb import session as chs
sess = chs.Session()
rows_cnt = 0
with sess.send_query("SELECT * FROM numbers(200000)", "CSV") as stream_result:
for chunk in stream_result:
rows_cnt += chunk.rows_read()
print(rows_cnt) # 200000
# Example 2: Manual iteration with fetch()
rows_cnt = 0
stream_result = sess.send_query("SELECT * FROM numbers(200000)", "CSV")
while True:
chunk = stream_result.fetch()
if chunk is None:
break
rows_cnt += chunk.rows_read()
print(rows_cnt) # 200000
For more details, see test_streaming_query.py.
import chdb.dbapi as dbapi
print("chdb driver version: {0}".format(dbapi.get_client_info()))
conn1 = dbapi.connect()
cur1 = conn1.cursor()
cur1.execute('select version()')
print("description: ", cur1.description)
print("data: ", cur1.fetchone())
cur1.close()
conn1.close()
import chdb.dataframe as cdf
import pandas as pd
# Join 2 DataFrames
df1 = pd.DataFrame({'a': [1, 2, 3], 'b': ["one", "two", "three"]})
df2 = pd.DataFrame({'c': [1, 2, 3], 'd': ["โ ", "โก", "โข"]})
ret_tbl = cdf.query(sql="select * from __tbl1__ t1 join __tbl2__ t2 on t1.a = t2.c",
tbl1=df1, tbl2=df2)
print(ret_tbl)
# Query on the DataFrame Table
print(ret_tbl.query('select b, sum(a) from __table__ group by b'))
# Pandas DataFrames are automatically registered as temporary tables in ClickHouse
chdb.query("SELECT * FROM Python(df1) t1 JOIN Python(df2) t2 ON t1.a = t2.c").show()
import chdb
import pandas as pd
df = pd.DataFrame(
{
"a": [1, 2, 3, 4, 5, 6],
"b": ["tom", "jerry", "auxten", "tom", "jerry", "auxten"],
}
)
chdb.query("SELECT b, sum(a) FROM Python(df) GROUP BY b ORDER BY b").show()
import chdb
import pyarrow as pa
arrow_table = pa.table(
{
"a": [1, 2, 3, 4, 5, 6],
"b": ["tom", "jerry", "auxten", "tom", "jerry", "auxten"],
}
)
chdb.query("SELECT b, sum(a) FROM Python(arrow_table) GROUP BY b ORDER BY b").show()
see also: test_query_py.py.
chDB supports native Python UDFs that run in-process with full type safety.
import chdb
from chdb.session import Session
from chdb.sqltypes import INT64, STRING
sess = Session()
# Using the @chdb.func decorator
@chdb.func([INT64, INT64], INT64)
def add(a, b):
return a + b
print(sess.query("SELECT add(12, 22)"))
# With type annotations (types inferred automatically)
@chdb.func()
def multiply(a: int, b: int) -> int:
return a * b
print(sess.query("SELECT multiply(3, 7)"))
# Using chdb.create_function directly
chdb.create_function("strlen", len, arg_types=[STRING], return_type=INT64)
print(sess.query("SELECT strlen('hello')"))
# Remove a registered function
chdb.drop_function("strlen")
Key features:
INT64, FLOAT64, STRING, BOOL, DATETIME64, etc. See chdb.sqltypes for full list.int, str, bool, etc.)on_null=NullHandling.SKIP (default) skips the function call and returns NULL; NullHandling.PASS passes None to the function.on_error=ExceptionHandling.PROPAGATE (default) raises the error to the caller; ExceptionHandling.IGNORE returns NULL for that row and continues.See also: test_func_udf.py, test_func_udf_types.py.
import chdb
# Auto-detect: TTY progress in terminal, progress bar in notebook
conn = chdb.connect(":memory:?progress=auto")
conn.query("SELECT sum(number) FROM numbers_mt(1e10) GROUP BY number % 10 SETTINGS max_threads=4")
Progress options: progress=auto | progress=tty | progress=err | progress=off
import chdb
conn = chdb.connect("file::memory:?ai_provider=openai&ai_model=gpt-4o-mini")
conn.query("CREATE TABLE nums (n UInt32) ENGINE = Memory")
conn.query("INSERT INTO nums VALUES (1), (2), (3)")
sql = conn.generate_sql("Select all rows from nums ordered by n desc")
print(sql) # SELECT * FROM nums ORDER BY n DESC
print(conn.ask("List the numbers table", format="Pretty"))
python3 -m chdb SQL [OutputFormat]
python3 -m chdb "SELECT 1,'abc'" Pretty
chDB provides an AI Skill that teaches AI coding agents (Cursor, Claude Code, etc.) chDB's multi-source data analytics API. Install it so your AI assistant can write correct chDB code out of the box:
curl -sL https://raw.githubusercontent.com/chdb-io/chdb/main/install_skill.sh | bash
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
We welcome bindings for other languages, please refer to bindings for more details.
Please refer to VERSION-GUIDE.md for more details.
Apache 2.0, see LICENSE for more information.
chDB is mainly based on ClickHouse 1 for trade mark and other reasons, I named it chDB.
ClickHouseยฎ is a trademark of ClickHouse Inc. All trademarks, service marks, and logos mentioned or depicted are the property of their respective owners. The use of any third-party trademarks, brand names, product names, and company names does not imply endorsement, affiliation, or association with the respective owners. โฉ โฉ2
C++
78.0%
Python
8.5%
Assembly
7.0%
C
2.5%
CMake
1.3%
HTML
1.1%
chDB is an in-process OLAP SQL Engine ๐ powered by ClickHouse
21
stars
3,815
commits
C++
primary language
Sep 8, 2026
updated
chdb-core is the foundational engine of the chDB ecosystem โ an in-process SQL OLAP Engine powered by ClickHouse 1
chdb-core (this repo) is the engine; chDB is a higher-level pandas-compatible DataStore API built on top of it (see the diagram below). The engine itself ships as five distribution artifacts โ three Python wheels (same import chdb, differing only by build flags) and two JavaScript/WASM packages:
| Artifact | How to get it | Target / runtime | Best for |
|---|---|---|---|
| chdb-core | PyPI โ pip install chdb-core | Python 3.9+ (Linux/macOS) | Default full build โ everything included |
| chdb-core-lite | PyPI โ pip install chdb-core-lite | Python 3.9+ (Linux/macOS) | Slimmer build that trims less-common features (e.g. external connectors like MySQL/Kafka) |
| chdb-core (free-threaded) | GitHub release assets | Free-threaded Python 3.14t (no GIL) | Running chDB without the GIL |
| chdb-wasm | npm โ npm install chdb-wasm | Browsers & Node (WebAssembly) | Running the full engine in the browser or Node |
| chdb-cloudflare | npm โ npm install chdb-cloudflare | Cloudflare Workers | A slimmer build for Cloudflare Workers |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ chDB (pip install chdb) โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ โ DataStore: pandas-like lazy API โ โ โ โ QueryPlanner / dual-engine exec โ โ โ โโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโ โ โ โ โ โ โโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโ โ โ โ chdb-core (pip install chdb-core) โ โ โ โ C++ ClickHouse Engine โ โ โ โ Session / Connection / DB-API โ โ โ โ query() / UDF / Stream โ โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
chdb-core provides everything you need to run SQL queries with ClickHouse performance โ no server required. If you want a higher-level pandas-compatible DataFrame API, install chDB instead.
Currently, chdb-core supports Python 3.9+ on macOS and Linux (x86_64 and ARM64).
pip install chdb-core
import chdb
result = chdb.query("SELECT version()", "Pretty")
print(result)
The simplest way to run SQL โ no session or connection needed:
import chdb
# Basic query with CSV output (default)
result = chdb.query("SELECT 1, 'hello'")
print(result)
# Pandas DataFrame output
df = chdb.query("SELECT number, number * 2 AS double FROM numbers(10)", "DataFrame")
print(df)
# Parameterized queries
df = chdb.query(
"SELECT toDate({base_date:String}) + number AS date "
"FROM numbers({total_days:UInt64}) "
"LIMIT {items_per_page:UInt64}",
"DataFrame",
params={"base_date": "2025-01-01", "total_days": 10, "items_per_page": 5},
)
print(df)
import chdb
res = chdb.query('SELECT * FROM file("data.parquet", Parquet)', "JSON")
print(res)
res = chdb.query('SELECT * FROM file("data.csv", CSV)', "CSV")
print(res)
# Query result statistics
print(f"SQL read {res.rows_read()} rows, {res.bytes_read()} bytes, "
f"storage read {res.storage_rows_read()} rows, {res.storage_bytes_read()} bytes, "
f"elapsed {res.elapsed()} seconds")
# Pandas DataFrame output
chdb.query('SELECT * FROM file("data.parquet", Parquet)', "Dataframe")
Connection-based API for cursor-style interaction, supporting both in-memory and file-based databases:
import chdb
conn = chdb.connect(":memory:")
cur = conn.cursor()
cur.execute("CREATE TABLE test (id UInt32, name String) ENGINE = Memory")
cur.execute("INSERT INTO test VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Charlie')")
cur.execute("SELECT * FROM test ORDER BY id")
print(cur.fetchone()) # (1, 'Alice')
print(cur.fetchmany(2)) # ((2, 'Bob'), (3, 'Charlie'))
print(cur.column_names()) # ['id', 'name']
print(cur.column_types()) # ['UInt32', 'String']
# Use the cursor as an iterator
cur.execute("SELECT number FROM system.numbers LIMIT 3")
for row in cur:
print(row)
# Always close resources when done
cur.close()
conn.close()
For more details, see examples/connect.py.
# File-based persistent database
conn = chdb.connect("mydata.db")
conn.query("CREATE TABLE IF NOT EXISTS logs (ts DateTime, msg String) ENGINE = MergeTree ORDER BY ts")
conn.query("INSERT INTO logs VALUES (now(), 'started')")
result = conn.query("SELECT * FROM logs", "Pretty")
print(result)
conn.close()
Sessions provide a higher-level API with automatic resource management:
from chdb import session as chs
sess = chs.Session()
sess.query("CREATE DATABASE IF NOT EXISTS db_xxx ENGINE = Atomic")
sess.query("CREATE TABLE IF NOT EXISTS db_xxx.log_table (x String, y Int) ENGINE = Log")
sess.query("INSERT INTO db_xxx.log_table VALUES ('a', 1), ('b', 3), ('c', 2), ('d', 5)")
sess.query("CREATE VIEW db_xxx.view_xxx AS SELECT * FROM db_xxx.log_table LIMIT 4")
print(sess.query("SELECT * FROM db_xxx.view_xxx", "Pretty"))
see also: test_stateful.py.
Process large datasets with constant memory usage through chunked streaming:
from chdb import session as chs
sess = chs.Session()
rows_cnt = 0
with sess.send_query("SELECT * FROM numbers(200000)", "CSV") as stream_result:
for chunk in stream_result:
rows_cnt += chunk.rows_read()
print(rows_cnt) # 200000
# Example 2: Manual iteration with fetch()
rows_cnt = 0
stream_result = sess.send_query("SELECT * FROM numbers(200000)", "CSV")
while True:
chunk = stream_result.fetch()
if chunk is None:
break
rows_cnt += chunk.rows_read()
print(rows_cnt) # 200000
For more details, see test_streaming_query.py.
import chdb.dbapi as dbapi
print("chdb driver version: {0}".format(dbapi.get_client_info()))
conn1 = dbapi.connect()
cur1 = conn1.cursor()
cur1.execute('select version()')
print("description: ", cur1.description)
print("data: ", cur1.fetchone())
cur1.close()
conn1.close()
import chdb.dataframe as cdf
import pandas as pd
# Join 2 DataFrames
df1 = pd.DataFrame({'a': [1, 2, 3], 'b': ["one", "two", "three"]})
df2 = pd.DataFrame({'c': [1, 2, 3], 'd': ["โ ", "โก", "โข"]})
ret_tbl = cdf.query(sql="select * from __tbl1__ t1 join __tbl2__ t2 on t1.a = t2.c",
tbl1=df1, tbl2=df2)
print(ret_tbl)
# Query on the DataFrame Table
print(ret_tbl.query('select b, sum(a) from __table__ group by b'))
# Pandas DataFrames are automatically registered as temporary tables in ClickHouse
chdb.query("SELECT * FROM Python(df1) t1 JOIN Python(df2) t2 ON t1.a = t2.c").show()
import chdb
import pandas as pd
df = pd.DataFrame(
{
"a": [1, 2, 3, 4, 5, 6],
"b": ["tom", "jerry", "auxten", "tom", "jerry", "auxten"],
}
)
chdb.query("SELECT b, sum(a) FROM Python(df) GROUP BY b ORDER BY b").show()
import chdb
import pyarrow as pa
arrow_table = pa.table(
{
"a": [1, 2, 3, 4, 5, 6],
"b": ["tom", "jerry", "auxten", "tom", "jerry", "auxten"],
}
)
chdb.query("SELECT b, sum(a) FROM Python(arrow_table) GROUP BY b ORDER BY b").show()
see also: test_query_py.py.
chDB supports native Python UDFs that run in-process with full type safety.
import chdb
from chdb.session import Session
from chdb.sqltypes import INT64, STRING
sess = Session()
# Using the @chdb.func decorator
@chdb.func([INT64, INT64], INT64)
def add(a, b):
return a + b
print(sess.query("SELECT add(12, 22)"))
# With type annotations (types inferred automatically)
@chdb.func()
def multiply(a: int, b: int) -> int:
return a * b
print(sess.query("SELECT multiply(3, 7)"))
# Using chdb.create_function directly
chdb.create_function("strlen", len, arg_types=[STRING], return_type=INT64)
print(sess.query("SELECT strlen('hello')"))
# Remove a registered function
chdb.drop_function("strlen")
Key features:
INT64, FLOAT64, STRING, BOOL, DATETIME64, etc. See chdb.sqltypes for full list.int, str, bool, etc.)on_null=NullHandling.SKIP (default) skips the function call and returns NULL; NullHandling.PASS passes None to the function.on_error=ExceptionHandling.PROPAGATE (default) raises the error to the caller; ExceptionHandling.IGNORE returns NULL for that row and continues.See also: test_func_udf.py, test_func_udf_types.py.
import chdb
# Auto-detect: TTY progress in terminal, progress bar in notebook
conn = chdb.connect(":memory:?progress=auto")
conn.query("SELECT sum(number) FROM numbers_mt(1e10) GROUP BY number % 10 SETTINGS max_threads=4")
Progress options: progress=auto | progress=tty | progress=err | progress=off
import chdb
conn = chdb.connect("file::memory:?ai_provider=openai&ai_model=gpt-4o-mini")
conn.query("CREATE TABLE nums (n UInt32) ENGINE = Memory")
conn.query("INSERT INTO nums VALUES (1), (2), (3)")
sql = conn.generate_sql("Select all rows from nums ordered by n desc")
print(sql) # SELECT * FROM nums ORDER BY n DESC
print(conn.ask("List the numbers table", format="Pretty"))
python3 -m chdb SQL [OutputFormat]
python3 -m chdb "SELECT 1,'abc'" Pretty
chDB provides an AI Skill that teaches AI coding agents (Cursor, Claude Code, etc.) chDB's multi-source data analytics API. Install it so your AI assistant can write correct chDB code out of the box:
curl -sL https://raw.githubusercontent.com/chdb-io/chdb/main/install_skill.sh | bash
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
We welcome bindings for other languages, please refer to bindings for more details.
Please refer to VERSION-GUIDE.md for more details.
Apache 2.0, see LICENSE for more information.
chDB is mainly based on ClickHouse 1 for trade mark and other reasons, I named it chDB.
ClickHouseยฎ is a trademark of ClickHouse Inc. All trademarks, service marks, and logos mentioned or depicted are the property of their respective owners. The use of any third-party trademarks, brand names, product names, and company names does not imply endorsement, affiliation, or association with the respective owners. โฉ โฉ2
C++
78.0%
Python
8.5%
Assembly
7.0%
C
2.5%
CMake
1.3%
HTML
1.1%