FastAPI proxy that exposes YTsaurus CHYT as a ClickHouse HTTP/JDBC endpoint for DBeaver, DataGrip and other SQL clients
Project description
ytsaurus-clickhouse-proxy
A lightweight FastAPI proxy that makes YTsaurus CHYT look like a native ClickHouse endpoint — so DBeaver, DataGrip and any JDBC client just works.
What it does
YTsaurus ships with CHYT — a ClickHouse-over-YT engine — but its HTTP interface isn't perfectly compatible with JDBC drivers.
ytsaurus-clickhouse-proxy sits in front of CHYT and:
- Intercepts
system.tables,system.columns,system.databasesqueries and returns a virtual catalog you define in a single Python file - Rewrites friendly table aliases (
analytics.orders) into real YT paths (//home/my_project/prod/orders) transparently - Handles both single tables and date-partitioned directories (
concatYtTablesRange) - Strips incompatible query parameters (e.g.
compress=1) before forwarding - Works out of the box with DBeaver, DataGrip, and any other JDBC ClickHouse client
DBeaver / DataGrip
│ JDBC (ClickHouse driver)
▼
ytsaurus-clickhouse-proxy :8123
│ Rewrites queries · Injects virtual catalog
▼
YTsaurus CHYT clique
│
▼
YT Tables
Installation
pip install ytsaurus-clickhouse-proxy
Or from source:
git clone https://github.com/klipbn/ytsaurus_clickhouse_proxy.git
cd ytsaurus-clickhouse-proxy
pip install -e .
Quick Start
1. Configure your table catalog
Edit yt_clickhouse_proxy/logical_catalog.py and describe which YT tables you want to see in your IDE:
LOGICAL_CATALOG = {
# Schema name visible in DBeaver
"analytics": {
# Alias → single YT table
"orders": {
"type": "table",
"path": "//home/my_project/prod/orders",
},
# Alias → date-partitioned directory
"events_1d": {
"type": "range",
"base": "//home/my_project/logs/events/1d",
"sample": "2024-01-01", # used for schema introspection
},
},
}
2. Set environment variables
export YT_PROXY=http://your-yt-cluster.example.com
export YT_TOKEN_PATH=~/.yt/token # file containing your OAuth token
export CLIQUE_ALIAS=ch_public # CHYT clique name
3. Run
ytsaurus-clickhouse-proxy
# or
python -m yt_clickhouse_proxy
# or with uvicorn directly
uvicorn yt_clickhouse_proxy:app --host 0.0.0.0 --port 8123
Connect from DBeaver
| Field | Value |
|---|---|
| Driver | ClickHouse |
| JDBC URL | jdbc:clickhouse://127.0.0.1:8123/analytics |
| Username | your CHYT clique alias (e.g. ch_public) |
| Password | your YT OAuth token |
Driver property compress |
false |
Driver property check_table_existence |
false |
Once connected, you'll see your logical schemas and tables in the navigator:
Environment Variables
| Variable | Default | Description |
|---|---|---|
YT_PROXY |
(required) | YTsaurus cluster HTTP address |
YT_TOKEN_PATH |
~/.yt/token |
Path to file containing your OAuth token |
CLIQUE_ALIAS |
ch_public |
CHYT clique alias |
DEFAULT_FORMAT |
RowBinaryWithNamesAndTypes |
ClickHouse wire format |
MAX_TABLES_IN_COLUMNS_UNION |
100 |
Max tables fetched in a single system.columns request |
Docker
Build and run
docker build -t ytsaurus-clickhouse-proxy .
docker run -d \
--name ytsaurus-clickhouse-proxy \
-p 8123:8123 \
-v ~/.yt/token:/root/.yt/token:ro \
-e YT_PROXY=http://your-yt-cluster.example.com \
-e CLIQUE_ALIAS=ch_public \
ytsaurus-clickhouse-proxy
With Docker Compose
# edit YT_PROXY in docker-compose.yml first
docker compose up -d
docker compose logs -f
Example SQL Queries
-- List all tables in your catalog
SELECT name, engine, database
FROM system.tables
WHERE database = 'analytics';
-- Inspect column types (JDBC metadata)
SELECT TABLE_NAME, COLUMN_NAME, TYPE_NAME, DATA_TYPE, ORDINAL_POSITION
FROM system.columns
WHERE TABLE_NAME = 'orders'
ORDER BY ORDINAL_POSITION;
-- Query data via alias
SELECT date, count() AS cnt
FROM analytics.events_1d
WHERE date >= '2024-01-01'
GROUP BY date
ORDER BY date;
-- Or pass a raw YT path directly (CHYT native syntax)
SELECT *
FROM concatYtTablesRange('//home/my_project/logs/events/1d', '2024-01-01', '2024-01-31')
LIMIT 100;
Logical Catalog Reference
LOGICAL_CATALOG = {
"<schema_name>": {
"<table_alias>": {
# ── Option A: single table ──────────────────────────────────
"type": "table",
"path": "//home/my_project/some_table",
# ── Option B: date-partitioned directory ────────────────────
"type": "range",
"base": "//home/my_project/logs/events/1d",
"sample": "2024-01-01", # one valid partition for DESCRIBE
},
},
}
type: "table"— proxied asSELECT … FROM `//path`type: "range"— proxied asSELECT … FROM concatYtTablesRange('base', …)with the full date range passed by the caller
Known Limitations
system.columnswithout a table filter returns a limited result set to avoid hitting CHYT'smax_query_sizelimit- No authentication layer — the proxy inherits your YT token; do not expose port 8123 publicly without a firewall
compress=1from JDBC is silently dropped (CHYT handles its own transport compression)
Contributing
Pull requests are welcome! Please open an issue first to discuss what you'd like to change.
git clone https://github.com/klipbn/ytsaurus_clickhouse_proxy.git
cd ytsaurus-clickhouse-proxy
pip install -e ".[dev]"
License
MIT © 2026 Alexey Voronko
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file ytsaurus_clickhouse_proxy-0.1.0.tar.gz.
File metadata
- Download URL: ytsaurus_clickhouse_proxy-0.1.0.tar.gz
- Upload date:
- Size: 12.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
399eafea94ea272786b28ae8acbed0a2dfb8aee21b7e6004345bafbc57b30344
|
|
| MD5 |
7f05f715df4108defeb888ba04d30195
|
|
| BLAKE2b-256 |
a5840448acf2e679eb6021c03af3fb378e4b24829aed695fb66b70f82a906e43
|