This is an automated email from the ASF dual-hosted git repository. lyndsi pushed a commit to branch lyndsi/sql-lab-new-explore-button-functionality-and-move-save-dataset-to-split-save-button in repository https://gitbox.apache.org/repos/asf/superset.git
commit 894e4013c7ad3a1ec63f1fc5694f0f870778bc19 Author: Hugh A. Miles II <[email protected]> AuthorDate: Tue Jun 21 13:26:52 2022 +0000 fix pre-commit to 50 errors now --- superset/common/query_context_factory.py | 2 +- superset/common/query_context_processor.py | 2 +- superset/models/helpers.py | 71 ++++++++++++++++++++---------- superset/models/sql_lab.py | 44 ++++++++++++++++++ superset/utils/core.py | 13 +++--- superset/views/core.py | 25 ++++------- 6 files changed, 109 insertions(+), 48 deletions(-) diff --git a/superset/common/query_context_factory.py b/superset/common/query_context_factory.py index c5a5d7cd1b..eefc5e6830 100644 --- a/superset/common/query_context_factory.py +++ b/superset/common/query_context_factory.py @@ -82,7 +82,7 @@ class QueryContextFactory: # pylint: disable=too-few-public-methods # pylint: disable=no-self-use def _convert_to_model(self, datasource: DatasourceDict) -> BaseDatasource: - from superset.dao.datasource.dao import DatasourceDAO + from superset.datasource.dao import DatasourceDAO from superset.utils.core import DatasourceType return DatasourceDAO.get_datasource( diff --git a/superset/common/query_context_processor.py b/superset/common/query_context_processor.py index e94af2d6ef..31f38cb839 100644 --- a/superset/common/query_context_processor.py +++ b/superset/common/query_context_processor.py @@ -124,7 +124,7 @@ class QueryContextProcessor: invalid_columns=invalid_columns, ) ) - + query_result = self.get_query_result(query_obj) annotation_data = self.get_annotation_data(query_obj) cache.set_query_result( diff --git a/superset/models/helpers.py b/superset/models/helpers.py index d52be71646..0992f2368a 100644 --- a/superset/models/helpers.py +++ b/superset/models/helpers.py @@ -61,14 +61,20 @@ from sqlalchemy_utils import UUIDType from superset import app, db, is_feature_enabled, security_manager from superset.common.db_query_status import QueryStatus +from superset.connectors.sqla import SqlMetric +from superset.db_engine_specs import BaseEngineSpec +from superset.errors import ErrorLevel, SupersetError, SupersetErrorType +from superset.exceptions import SupersetSecurityException from superset.jinja_context import ( BaseTemplateProcessor, ExtraCache, get_template_processor, ) +from superset.models.core import Database from superset.sql_parse import ( extract_table_references, has_table_query, + insert_rls, ParsedQuery, sanitize_clause, Table as TableName, @@ -669,47 +675,64 @@ class ExploreMixin: } @property - def owners_data(self): - return [] + def owners_data(self) -> List[Any]: + raise NotImplementedError() @property - def metrics(self): - return [] + def metrics(self) -> List[Any]: + raise NotImplementedError() @property - def uid(self): - return "foo" + def uid(self) -> str: + raise NotImplementedError() @property - def is_rls_supported(self): - return False + def is_rls_supported(self) -> bool: + raise NotImplementedError() @property - def cache_timeout(self): - return None + def cache_timeout(self) -> int: + raise NotImplementedError() @property - def column_names(self): - return [col.get("column_name") for col in self.columns] + def column_names(self) -> List[str]: + raise NotImplementedError() @property - def offset(self): - return 0 + def offset(self) -> int: + raise NotImplementedError() @property def main_dttm_col(self) -> str: - for col in self.columns: - if col.get('is_dttm'): - return col.get('column_name') - return None + raise NotImplementedError() @property def dttm_cols(self) -> List[str]: - return [col.get('column_name') for col in self.columns if col.get('is_dttm')] + raise NotImplementedError() + + @property + def db_engine_spec(self) -> Type["BaseEngineSpec"]: + raise NotImplementedError() + + @property + def database(self) -> Type["Database"]: + raise NotImplementedError() + + @property + def schema(self) -> str: + raise NotImplementedError() + + @property + def sql(self) -> str: + raise NotImplementedError() + + @property + def columns(self) -> List[Any]: + raise NotImplementedError() @staticmethod - def get_extra_cache_keys(query_obj): - return [] + def get_extra_cache_keys(query_obj: Dict[str, Any]) -> List[str]: + raise NotImplementedError() def make_sqla_column_compatible( self, sqla_col: ColumnElement, label: Optional[str] = None @@ -1649,13 +1672,13 @@ class ExploreMixin: inner_groupby_exprs = [] inner_select_exprs = [] for gby_name, gby_obj in groupby_series_columns.items(): - label = get_column_name(gby_name) + label = utils.get_column_name(gby_name) inner = self.make_sqla_column_compatible(gby_obj, gby_name + "__") inner_groupby_exprs.append(inner) inner_select_exprs.append(inner) inner_select_exprs += [inner_main_metric_expr] - subq = select(inner_select_exprs).select_from(tbl) + subq = sa.select(inner_select_exprs).select_from(tbl) inner_time_filter = [] if dttm_col and not db_engine_spec.time_groupby_inline: @@ -1683,7 +1706,7 @@ class ExploreMixin: # conditionally mutated, as it refers to the column alias in # the inner query col_name = db_engine_spec.make_label_compatible(gby_name + "__") - on_clause.append(gby_obj == column(col_name)) + on_clause.append(gby_obj == sa.column(col_name)) tbl = tbl.join(subq.alias(), and_(*on_clause)) else: diff --git a/superset/models/sql_lab.py b/superset/models/sql_lab.py index 5a9bf91de3..84061a65bc 100644 --- a/superset/models/sql_lab.py +++ b/superset/models/sql_lab.py @@ -40,6 +40,7 @@ from sqlalchemy.engine.url import URL from sqlalchemy.orm import backref, relationship from superset import security_manager +from superset.db_engine_specs import BaseEngineSpec from superset.models.helpers import ( AuditMixinNullable, ExploreMixin, @@ -247,6 +248,49 @@ class Query(Model, ExtraJSONMixin, ExploreMixin): def db_engine_spec(self) -> Type["BaseEngineSpec"]: return self.database.db_engine_spec + @property + def owners_data(self): + return [] + + @property + def metrics(self): + return [] + + @property + def uid(self): + return "foo" + + @property + def is_rls_supported(self): + return False + + @property + def cache_timeout(self): + return None + + @property + def column_names(self): + return [col.get("column_name") for col in self.columns] + + @property + def offset(self): + return 0 + + @property + def main_dttm_col(self) -> str: + for col in self.columns: + if col.get("is_dttm"): + return col.get("column_name") + return None + + @property + def dttm_cols(self) -> List[Any]: + return [col.get("column_name") for col in self.columns if col.get("is_dttm")] + + @staticmethod + def get_extra_cache_keys(query_obj: Dict[str, Any]) -> List[str]: + return [] + class SavedQuery(Model, AuditMixinNullable, ExtraJSONMixin, ImportExportMixin): """ORM model for SQL query""" diff --git a/superset/utils/core.py b/superset/utils/core.py index ceb49268b1..0ecff893c5 100644 --- a/superset/utils/core.py +++ b/superset/utils/core.py @@ -1674,26 +1674,27 @@ def extract_dataframe_dtypes( "date": GenericDataType.TEMPORAL, } - # todo(hughhhh): can we make the column_object a Union + # todo(hughhhh): can we make the column_object a Union if datasource and datasource.type == "query": - columns_by_name = {column.get('column_name'): column for column in datasource.columns} + columns_by_name = { + column.get("column_name"): column for column in datasource.columns + } else: columns_by_name = ( {column.column_name: column for column in datasource.columns} if datasource else {} ) - + generic_types: List[GenericDataType] = [] for column in df.columns: column_object = columns_by_name.get(column) series = df[column] inferred_type = infer_dtype(series) - # todo(hughhhh): can we make the column_object a Union - if datasource.type == "query": + if datasource and datasource.type == "query": # type: ignore generic_type = ( GenericDataType.TEMPORAL - if column_object and column_object.get('is_dttm') + if column_object and column_object.get("is_dttm") else inferred_type_map.get(inferred_type, GenericDataType.STRING) ) else: diff --git a/superset/views/core.py b/superset/views/core.py index 13942aca82..ab8604b602 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -776,15 +776,23 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods value = GetFormDataCommand(parameters).run() initial_form_data = json.loads(value) if value else {} - from superset.dao.datasource.dao import DatasourceDAO + from superset.datasource.dao import DatasourceDAO from superset.models.helpers import ExploreMixin from superset.utils.core import DatasourceType # Handle SIP-68 Models or explore view # API will always use /explore/<datasource_type>/<int:datasource_id>/ to query # new models to power any viz in explore + datasource: Optional[BaseDatasource] = None datasource_id = request.args.get("datasource_id", datasource_id) datasource_type = request.args.get("datasource_type", datasource_type) + dummy_datasource_data: Dict[str, Any] = { + "type": datasource_type, + "name": "[Missing Dataset]", + "columns": [], + "metrics": [], + "database": {"id": 0, "backend": ""}, + } if datasource_id and datasource_type: # 1. Query datasource object by type and id @@ -859,13 +867,6 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods ) standalone_mode = ReservedUrlParameters.is_standalone_mode() force = request.args.get("force") in {"force", "1", "true"} - dummy_datasource_data: Dict[str, Any] = { - "type": datasource_type, - "name": datasource_name, - "columns": [], - "metrics": [], - "database": {"id": 0, "backend": ""}, - } try: datasource_data = ( datasource.data if datasource else dummy_datasource_data @@ -932,7 +933,6 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods # fallback unkonw datasource to table type datasource_type = SqlaTable.type - datasource: Optional[BaseDatasource] = None if datasource_id is not None: try: datasource = DatasourceDAO.get_datasource( @@ -1018,13 +1018,6 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods ) standalone_mode = ReservedUrlParameters.is_standalone_mode() force = request.args.get("force") in {"force", "1", "true"} - dummy_datasource_data: Dict[str, Any] = { - "type": datasource_type, - "name": datasource_name, - "columns": [], - "metrics": [], - "database": {"id": 0, "backend": ""}, - } try: datasource_data = datasource.data if datasource else dummy_datasource_data except (SupersetException, SQLAlchemyError):
