Universal semantic layer - import from Cube, dbt, LookML, Hex, and more
Project description
Sidemantic
SQL-first semantic layer for consistent metrics across your data stack. Compatible with many other semantic model formats.
- Formats: Sidemantic, Cube, MetricFlow (dbt), LookML, Hex, Rill, Superset, Omni, BSL, Snowflake Cortex, Malloy
- Databases: DuckDB, MotherDuck, PostgreSQL, BigQuery, Snowflake, ClickHouse, Databricks, Spark SQL
Documentation | GitHub | Discord | Demo (50+ MB download)
Should I use Sidemantic
As you might notice, Sidemantic is a very ambitious and young semantic layer project. You will likely encounter some rough patches, especially with the more exotic features like converting between semantic model formats.
For the time being it is recommended to use one of the formats that Sidemantic can read as your source of truth.
Issue reports are much appreciated if you try out Sidemantic and hit a snag 🫡
Quickstart
Install:
uv add sidemantic
Malloy support (uv):
uv add "sidemantic[malloy]"
Notebook widget (uv):
uv add "sidemantic[widget]" jupyterlab
uv run jupyter lab
Marimo (uv):
uv add "sidemantic[widget]" marimo
uv run marimo edit
import duckdb
from sidemantic.widget import MetricsExplorer
conn = duckdb.connect(":memory:")
conn.execute("create table t as select 1 as value, 'a' as category, date '2024-01-01' as d")
MetricsExplorer(conn.table("t"), time_dimension="d")
Define models in SQL, YAML, or Python:
SQL (orders.sql)
MODEL (name orders, table orders, primary_key order_id);
DIMENSION (name status, type categorical);
DIMENSION (name order_date, type time, granularity day);
METRIC (name revenue, agg sum, sql amount);
METRIC (name order_count, agg count);
YAML (orders.yml)
models:
- name: orders
table: orders
primary_key: order_id
dimensions:
- name: status
type: categorical
- name: order_date
type: time
granularity: day
metrics:
- name: revenue
agg: sum
sql: amount
- name: order_count
agg: count
Python (programmatic)
from sidemantic import Model, Dimension, Metric
orders = Model(
name="orders",
table="orders",
primary_key="order_id",
dimensions=[
Dimension(name="status", type="categorical"),
Dimension(name="order_date", type="time", granularity="day"),
],
metrics=[
Metric(name="revenue", agg="sum", sql="amount"),
Metric(name="order_count", agg="count"),
]
)
Query via CLI:
sidemantic query "SELECT revenue, status FROM orders" --db data.duckdb
Or Python API:
from sidemantic import SemanticLayer, load_from_directory
layer = SemanticLayer(connection="duckdb:///data.duckdb")
load_from_directory(layer, "models/")
result = layer.sql("SELECT revenue, status FROM orders")
CLI
# Query
sidemantic query "SELECT revenue FROM orders" --db data.duckdb
# Interactive workbench (TUI with SQL editor + charts)
sidemantic workbench models/ --db data.duckdb
# PostgreSQL server (connect Tableau, DBeaver, etc.)
sidemantic serve models/ --port 5433
# Validate definitions
sidemantic validate models/
# Model info
sidemantic info models/
# Pre-aggregation recommendations
sidemantic preagg recommend --db data.duckdb
# Migrate SQL queries to semantic layer
sidemantic migrator --queries legacy/ --generate-models output/
Demos
Workbench (TUI with SQL editor + charts):
uvx sidemantic workbench --demo
PostgreSQL server (connect Tableau, DBeaver, etc.):
uvx sidemantic serve --demo --port 5433
Colab notebooks:
SQL syntax:
uv run https://raw.githubusercontent.com/sidequery/sidemantic/main/examples/sql/sql_syntax_example.py
Comprehensive demo:
uv run https://raw.githubusercontent.com/sidequery/sidemantic/main/examples/advanced/comprehensive_demo.py
Symmetric aggregates:
uv run https://raw.githubusercontent.com/sidequery/sidemantic/main/examples/features/symmetric_aggregates_example.py
Superset with DuckDB:
git clone https://github.com/sidequery/sidemantic.git && cd sidemantic
uv run examples/superset_demo/run_demo.py
Cube Playground:
git clone https://github.com/sidequery/sidemantic.git && cd sidemantic
uv run examples/cube_demo/run_demo.py
Rill Developer:
git clone https://github.com/sidequery/sidemantic.git && cd sidemantic
uv run examples/rill_demo/run_demo.py
See examples/ for more.
Core Features
- SQL query interface with automatic rewriting
- Automatic joins across models
- Multi-format adapters (Cube, MetricFlow, LookML, Hex, Rill, Superset, Omni, BSL)
- SQLGlot-based SQL generation and transpilation
- Pydantic validation and type safety
- Pre-aggregations with automatic routing
- Predicate pushdown for faster queries
- Segments and metric-level filters
- Jinja2 templating for dynamic SQL
- PostgreSQL wire protocol server for BI tools
Multi-Format Support
Auto-detects: Sidemantic (SQL/YAML), Cube, MetricFlow (dbt), LookML, Hex, Rill, Superset, Omni, BSL
sidemantic query "SELECT revenue FROM orders" --models ./my_models
from sidemantic import SemanticLayer, load_from_directory
layer = SemanticLayer(connection="duckdb:///data.duckdb")
load_from_directory(layer, "my_models/") # Auto-detects formats
Databases
| Database | Status | Installation |
|---|---|---|
| DuckDB | ✅ | built-in |
| MotherDuck | ✅ | built-in |
| PostgreSQL | ✅ | uv add sidemantic[postgres] |
| BigQuery | ✅ | uv add sidemantic[bigquery] |
| Snowflake | ✅ | uv add sidemantic[snowflake] |
| ClickHouse | ✅ | uv add sidemantic[clickhouse] |
| Databricks | ✅ | uv add sidemantic[databricks] |
| Spark SQL | ✅ | uv add sidemantic[spark] |
Testing
uv run pytest -v
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sidemantic-0.5.5.tar.gz.
File metadata
- Download URL: sidemantic-0.5.5.tar.gz
- Upload date:
- Size: 685.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50515ea78adb1046d24bb9f3670887a8ed24cb9b01b7971f4e9a00a392f678ec
|
|
| MD5 |
206c7b64008c36a88c42635b1d20c42f
|
|
| BLAKE2b-256 |
bc3602b37d5a7093d20536b0031e2d9a9a2f370553a76e52fd435e870a8a2e1f
|
File details
Details for the file sidemantic-0.5.5-py3-none-any.whl.
File metadata
- Download URL: sidemantic-0.5.5-py3-none-any.whl
- Upload date:
- Size: 459.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.24 {"installer":{"name":"uv","version":"0.9.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4399ccd808d7fc697fdec8ffd640f5549dbc9b08308b347b368a612e027a7aba
|
|
| MD5 |
e2e5a2773e3b238b2c0c23b9c05ab40d
|
|
| BLAKE2b-256 |
4fa84307004a009ea891cd675f381afa8abb674f5c5169ea257921cf20fcb4fa
|