This is an automated email from the ASF dual-hosted git repository. beto pushed a commit to branch explorable in repository https://gitbox.apache.org/repos/asf/superset.git
commit 4d83840f8138baeed4f026e988ae81e4db31a9a3 Author: Beto Dealmeida <[email protected]> AuthorDate: Tue Oct 14 15:54:04 2025 -0400 Working on get_values --- superset/semantic_layers/snowflake_.py | 48 +++++++++++++++++++++++++++++++--- superset/semantic_layers/types.py | 32 ++++++++++++++++++++++- 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/superset/semantic_layers/snowflake_.py b/superset/semantic_layers/snowflake_.py index 9d4ed78c04..be1dab9414 100644 --- a/superset/semantic_layers/snowflake_.py +++ b/superset/semantic_layers/snowflake_.py @@ -43,8 +43,10 @@ from superset.semantic_layers.types import ( DATETIME, DECIMAL, Dimension, + Filter, INTEGER, Metric, + NativeFilter, NUMBER, OBJECT, STRING, @@ -207,7 +209,6 @@ def get_connection_parameters(configuration: SnowflakeConfiguration) -> dict[str class SnowflakeSemanticLayer: - configuration_schema = SnowflakeConfiguration @classmethod @@ -436,6 +437,44 @@ class SnowflakeExplorable: return metrics + def get_values( + self, + dimension: Dimension, + filters: set[Filter | NativeFilter] | None = None, + ) -> set[Any]: + """ + Return distinct values for a dimension. + """ + native_filters = { + ( + filter_ + if isinstance(filter_, NativeFilter) + else self._build_native_filter(filter_) + ) + for filter_ in (filters or set()) + } + parenthesized = {f"({filter_.definition})" for filter_ in native_filters} + predicates = f"WHERE {' AND '.join(parenthesized)}" if parenthesized else "" + + query = f""" + SELECT {self._quote(dimension.name)} + FROM + SEMANTIC_VIEW( + {self.uid()} + DIMENSIONS {self._quote(dimension.id)} + ) + {predicates} + """ # noqa: S608 + connection_parameters = get_connection_parameters(self.configuration) + with connect(**connection_parameters) as connection: + cursor = connection.cursor(DictCursor) + return {row[0] for row in cursor.execute(query)} + + def _build_native_filter_(self, filter_: Filter) -> NativeFilter: + """ + Convert a Filter to a NativeFilter. + """ + def _get_type(self, snowflake_type: str | None) -> type[Type]: """ Return the semantic type corresponding to a Snowflake type. @@ -467,18 +506,19 @@ class SnowflakeExplorable: if __name__ == "__main__": + import os configuration = SnowflakeConfiguration.model_validate( { - "account_identifier": "KFTRUWN-VX32922", + "account_identifier": "hxjhxcj-oxc09268", "role": "ACCOUNTADMIN", "warehouse": "COMPUTE_WH", "database": "SAMPLE_DATA", "schema": "TPCDS_SF10TCL", "auth": { "auth_type": "user_password", - "username": "vavila", - "password": "XXX", + "username": os.environ["SNOWFLAKE_USER"], + "password": os.environ["SNOWFLAKE_PASSWORD"], }, "allow_changing_database": True, "allow_changing_schema": True, diff --git a/superset/semantic_layers/types.py b/superset/semantic_layers/types.py index 8ffcb4f1c2..eb4ef5e341 100644 --- a/superset/semantic_layers/types.py +++ b/superset/semantic_layers/types.py @@ -17,7 +17,7 @@ import enum from dataclasses import dataclass -from datetime import timedelta +from datetime import date, datetime, time, timedelta from functools import total_ordering __all__ = [ @@ -161,3 +161,33 @@ class Metric: definition: str description: str | None = None + + +class Operator(enum.Enum): + EQUALS = "=" + NOT_EQUALS = "!=" + GREATER_THAN = ">" + LESS_THAN = "<" + GREATER_THAN_OR_EQUAL = ">=" + LESS_THAN_OR_EQUAL = "<=" + IN = "IN" + NOT_IN = "NOT IN" + LIKE = "LIKE" + NOT_LIKE = "NOT LIKE" + IS_NULL = "IS NULL" + IS_NOT_NULL = "IS NOT NULL" + + +FilterTypes = str | int | float | bool | datetime | date | time | timedelta | None + + +@dataclass(frozen=True) +class Filter: + column: Dimension | Metric + operator: Operator + value: FilterTypes | set[FilterTypes] + + +@dataclass(frozen=True) +class NativeFilter: + definition: str
