A powerful DAX to SQL parser and translator with multi-dialect support.
Project description
A powerful Python library for parsing DAX (Data Analysis Expressions) queries and translating them into various SQL dialects (optimized for Trino).
Key Features
- Unified API: Simple
DaxParserclass for all your translation needs. - Metadata-Aware: Automatic column resolution and implicit JOIN injection based on your data model relationships.
- Multi-Dialect Support: Deeply optimized for Trino, with an extensible architecture for other engines.
- Multi-Schema/Catalog Resolution: Support for dotted table names and dynamic schema remapping.
- Detailed Error Reporting: Precise
DaxParsingErrorwith character offsets, ideal for IDEs and gateways. - Advanced DAX Support:
- Complex filtering (
FILTER,CALCULATETABLE) - Aggregations (
SUMMARIZE,ADDCOLUMNS,SELECTCOLUMNS) - Table operators (
UNION,INTERSECT,EXCEPT,GENERATE,CROSSJOIN) - Variables (
VAR...RETURN) - Logical operators and expressions (
IN,&&,||, etc.)
- Complex filtering (
Installation
pip install dax-sql-parser
Quick Start
from dax_sql_parser import DaxParser
# Initialize the parser
parser = DaxParser(default_dialect="trino")
# Translate a simple query
dax = "EVALUATE 'Sales'"
sql = parser.to_sql(dax)
print(sql)
# SELECT * FROM "Sales"
# Use schema mapping
parser = DaxParser(schema_mapping={"S": "raw.sales_data"})
sql = parser.to_sql("EVALUATE S")
print(sql)
# SELECT * FROM "raw"."sales_data"
Metadata and Implicit Joins
To support unqualified column references and automatic joins (critical for simple BI queries), provide a MetadataResolver.
from dax_sql_parser import DaxParser
from dax_sql_parser.core.metadata import MetadataResolver, TableMetadata, Relationship
# 1. Define your model
product = TableMetadata(name="Product")
product.add_column("ProductID", data_type="int")
product.add_column("Color", data_type="string")
sales = TableMetadata(name="Sales")
sales.add_column("ProductID", data_type="int")
sales.add_column("Amount", data_type="decimal")
# 2. Define relationships
rel = Relationship(from_table="Sales", from_column="ProductID",
to_table="Product", to_column="ProductID")
metadata = MetadataResolver(tables=[product, sales], relationships=[rel])
# 3. Initialize parser with metadata
parser = DaxParser(metadata=metadata)
# 4. Resolve unqualified [Color] and inject JOIN
dax = "EVALUATE FILTER('Sales', [Color] = \"Red\")"
sql = parser.to_sql(dax)
# SELECT * FROM Sales INNER JOIN Product ON ... WHERE Product.Color = 'Red'
Extending Dialects
dax-sql-parser is designed to be easily extensible. To add a new SQL dialect:
- Create a Dialect Class: Inherit from
BaseDialectand implementget_function_mappings. - Register the Dialect: Use
DialectRegistry.register().
from dax_sql_parser.core.dialects.base import BaseDialect
from dax_sql_parser.core.dialects.registry import DialectRegistry
import sqlglot.expressions as exp
class MySnowflakeDialect(BaseDialect):
@property
def name(self) -> str:
return "snowflake"
def get_function_mappings(self):
return {
"MEDIAN": lambda args: exp.Anonymous(this="MEDIAN", expressions=args)
}
DialectRegistry.register(MySnowflakeDialect())
Development & Testing
This project uses uv for dependency management and building.
Setup
- Install uv: Follow the official installation guide.
- Clone the repository:
git clone https://github.com/shohamyamin/dax-sql-parser.git cd dax-sql-parser
- Sync dependencies:
uv sync
Working with Grammar
The parser is based on ANTLR4. If you modify the grammar file src/dax_sql_parser/grammar/Dax.g4, you need to regenerate the Python files:
# Using antlr4-tools (installed via dev dependencies)
antlr4 -Dlanguage=Python3 -visitor -o src/dax_sql_parser/grammar/ src/dax_sql_parser/grammar/Dax.g4
Running Tests
Run the comprehensive test suite with pytest:
uv run pytest
To run with coverage report:
uv run pytest --cov=dax_sql_parser --cov-report=term-missing
Building the Package
To build the source distribution and wheel:
uv build
The artifacts will be generated in the dist/ directory.
License
MIT
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 dax_sql_parser-0.1.0.tar.gz.
File metadata
- Download URL: dax_sql_parser-0.1.0.tar.gz
- Upload date:
- Size: 32.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d1881743fe50f0e0687f14fbbfc746311d06032272f67e3c531b50f1403eec4
|
|
| MD5 |
2145170e9e2603ecb6fbd64c89800216
|
|
| BLAKE2b-256 |
5e782ba35bda732d35abcde34da627fb65be86c9707d97694f25cb8c0bb1b189
|
File details
Details for the file dax_sql_parser-0.1.0-py3-none-any.whl.
File metadata
- Download URL: dax_sql_parser-0.1.0-py3-none-any.whl
- Upload date:
- Size: 40.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c354e17e09aec238bdd6b193065fc9ea463ace5c7b793a547a174b27ad0a2f93
|
|
| MD5 |
c1fcbee9318be0ed3ce8a7109a1b012c
|
|
| BLAKE2b-256 |
a55511793a84f727c732fea3d683b6fb6a7474ca40395e39c8c4b59e67429bcb
|