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
Metadata
Release files for iflow-mcp_sidequery-sidemantic 0.5.11
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| iflow_mcp_sidequery_sidemantic-0.5.11.tar.gz | 1.0 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| iflow_mcp_sidequery_sidemantic-0.5.11-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.5 MB
Release files / iflow_mcp_sidequery_sidemantic-0.5.11.tar.gz
| Download URL | iflow_mcp_sidequery_sidemantic-0.5.11.tar.gz |
|---|---|
| Size | 1.0 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dddef8f47839324865e6500aa221b58ccc540277487010d4f55cab94ee07655c
|
|
BLAKE2b-256 checksum How to use checksums |
ddb1d234fb574f286490c529f8d5bc7f08c4b5d5df831158dd0c7bfafcfd0c90
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / iflow_mcp_sidequery_sidemantic-0.5.11-py3-none-any.whl
| Download URL | iflow_mcp_sidequery_sidemantic-0.5.11-py3-none-any.whl |
|---|---|
| Size | 474.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a08df0bece0d1514509232c6f407a6fb74f19076973ff25c0b3fbab253a0c9d4
|
|
BLAKE2b-256 checksum How to use checksums |
a64a091ee20c3d4e88a2628f0bcb0951c9e63f6c4e36cef45e4bf8d959cfefc3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|