Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POC - Enable support for clickhouse on SL #1592

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
31 changes: 30 additions & 1 deletion .github/workflows/cd-sql-engine-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,39 @@ jobs:
python-version: "3.12"
make-target: "test-trino"

clickhouse-tests:
# Clickhouse tests run on a local service container, which obviates the need for separate Environment hosting.
# We run them here instead of in the CI unit test suite because they are a bit slower, and because in future
# we may choose to execute them against a hosted instance, at which point this config will look like the other
# engine configs in this file.
name: Clickhouse Tests
if: ${{ github.event.action != 'labeled' || github.event.label.name == 'Run Tests With Other SQL Engines' }}
runs-on: ubuntu-latest
services:
clickhouse:
image: clickhouse/clickhouse-server
ports:
- 8123:8123
env:
CLICKHOUSE_USER: "metricflow"
CLICKHOUSE_PASSWORD: "metricflowing"
CLICKHOUSE_DB: "metricflow"
steps:
- name: Check-out the repo
uses: actions/checkout@v3

- name: Test w/ Python 3.12
uses: ./.github/actions/run-mf-tests
with:
python-version: "3.12"
make-target: "test-clickhouse"
mf_sql_engine_url: "clickhouse://metricflow:metricflowing@localhost:8123/metricflow"
mf_sql_engine_password: "metricflowing"

remove-label:
name: Remove Label After Running Tests
runs-on: ubuntu-latest
needs: [ snowflake-tests, redshift-tests, bigquery-tests, databricks-tests ]
needs: [ snowflake-tests, redshift-tests, bigquery-tests, databricks-tests, clickhouse-tests ]
# Default behavior for `needs` is that it requires success, so a success / failure needs to be specifically checked.
if: ${{ (success() || failure()) && github.event.action == 'labeled' }}
steps:
Expand Down
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ populate-persistent-source-schema-snowflake:
test-trino:
hatch -v run trino-env:pytest -vv -n $(PARALLELISM) $(ADDITIONAL_PYTEST_OPTIONS) $(TESTS_METRICFLOW)/

.PHONY: test-clickhouse
test-clickhouse:
hatch -v run clickhouse-env:pytest -vv -n $(PARALLELISM) $(ADDITIONAL_PYTEST_OPTIONS) $(TESTS_METRICFLOW)/

.PHONY: populate-persistent-source-schema-clickhouse
populate-persistent-source-schema-clickhouse:
hatch -v run clickhouse-env:pytest -vv $(ADDITIONAL_PYTEST_OPTIONS) $(USE_PERSISTENT_SOURCE_SCHEMA) $(POPULATE_PERSISTENT_SOURCE_SCHEMA)

.PHONY: lint
lint:
hatch -v run dev-env:pre-commit run --all-files
Expand All @@ -84,6 +92,10 @@ postgresql postgres:
trino:
make -C local-data-warehouses trino

.PHONY: clickhouse
clickhouse:
make -C local-data-warehouses clickhouse

# Re-generate test snapshots using all supported SQL engines.
.PHONY: regenerate-test-snapshots
regenerate-test-snapshots:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from metricflow.data_table.mf_table import MetricFlowDataTable
from metricflow.protocols.sql_client import SqlEngine
from metricflow.sql.render.big_query import BigQuerySqlQueryPlanRenderer
from metricflow.sql.render.clickhouse import ClickhouseSqlQueryPlanRenderer
from metricflow.sql.render.databricks import DatabricksSqlQueryPlanRenderer
from metricflow.sql.render.duckdb_renderer import DuckDbSqlQueryPlanRenderer
from metricflow.sql.render.postgres import PostgresSQLSqlQueryPlanRenderer
Expand Down Expand Up @@ -42,6 +43,7 @@ class SupportedAdapterTypes(enum.Enum):
BIGQUERY = "bigquery"
DUCKDB = "duckdb"
TRINO = "trino"
CLICKHOUSE = "clickhouse"

@property
def sql_engine_type(self) -> SqlEngine:
Expand All @@ -60,6 +62,8 @@ def sql_engine_type(self) -> SqlEngine:
return SqlEngine.DUCKDB
elif self is SupportedAdapterTypes.TRINO:
return SqlEngine.TRINO
elif self is SupportedAdapterTypes.CLICKHOUSE:
return SqlEngine.CLICKHOUSE
else:
assert_values_exhausted(self)

Expand All @@ -80,6 +84,8 @@ def sql_query_plan_renderer(self) -> SqlQueryPlanRenderer:
return DuckDbSqlQueryPlanRenderer()
elif self is SupportedAdapterTypes.TRINO:
return TrinoSqlQueryPlanRenderer()
elif self is SupportedAdapterTypes.CLICKHOUSE:
return ClickhouseSqlQueryPlanRenderer()
else:
assert_values_exhausted(self)

Expand Down
4 changes: 4 additions & 0 deletions local-data-warehouses/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ postgresql:
.PHONY: trino
trino:
docker-compose -f trino/docker-compose.yaml up

.PHONY: clickhouse
clickhouse:
docker-compose -f clickhouse/docker-compose.yaml up
16 changes: 16 additions & 0 deletions local-data-warehouses/clickhouse/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: "3.7"

services:
clickhouse:
container_name: clickhouse
image: clickhouse/clickhouse-server
expose:
- "8123"
- "9000"
ports:
- "8123:8123"
- "9000:9000"
environment:
CLICKHOUSE_USER: "metricflow"
CLICKHOUSE_PASSWORD: "metricflowing"
CLICKHOUSE_DB: "metricflow"
3 changes: 3 additions & 0 deletions metricflow/protocols/sql_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class SqlEngine(Enum):
SNOWFLAKE = "Snowflake"
DATABRICKS = "Databricks"
TRINO = "Trino"
CLICKHOUSE = "Clickhouse"

@property
def unsupported_granularities(self) -> Set[TimeGranularity]:
Expand All @@ -49,6 +50,8 @@ def unsupported_granularities(self) -> Set[TimeGranularity]:
return {TimeGranularity.NANOSECOND}
elif self is SqlEngine.TRINO:
return {TimeGranularity.NANOSECOND, TimeGranularity.MICROSECOND}
elif self is SqlEngine.CLICKHOUSE:
return {TimeGranularity.NANOSECOND, TimeGranularity.MICROSECOND}
else:
assert_values_exhausted(self)

Expand Down
Loading
Loading