From 7ef06b0a60874761cf0ccfcecb13cf0a89cb9e3e Mon Sep 17 00:00:00 2001 From: Kamil Gabryjelski Date: Mon, 20 Mar 2023 22:54:20 +0100 Subject: [PATCH 1/4] chore: Add DRILL_BY feature flag (#23430) --- .../packages/superset-ui-core/src/utils/featureFlags.ts | 1 + superset/config.py | 1 + 2 files changed, 2 insertions(+) diff --git a/superset-frontend/packages/superset-ui-core/src/utils/featureFlags.ts b/superset-frontend/packages/superset-ui-core/src/utils/featureFlags.ts index 1492d83846e39..132d48c7a6767 100644 --- a/superset-frontend/packages/superset-ui-core/src/utils/featureFlags.ts +++ b/superset-frontend/packages/superset-ui-core/src/utils/featureFlags.ts @@ -38,6 +38,7 @@ export enum FeatureFlag { DISABLE_LEGACY_DATASOURCE_EDITOR = 'DISABLE_LEGACY_DATASOURCE_EDITOR', DISPLAY_MARKDOWN_HTML = 'DISPLAY_MARKDOWN_HTML', DRILL_TO_DETAIL = 'DRILL_TO_DETAIL', + DRILL_BY = 'DRILL_BY', DYNAMIC_PLUGINS = 'DYNAMIC_PLUGINS', EMBEDDABLE_CHARTS = 'EMBEDDABLE_CHARTS', EMBEDDED_SUPERSET = 'EMBEDDED_SUPERSET', diff --git a/superset/config.py b/superset/config.py index 4671e203c8c73..c9234e521d754 100644 --- a/superset/config.py +++ b/superset/config.py @@ -478,6 +478,7 @@ def _try_json_readsha(filepath: str, length: int) -> Optional[str]: # Enable sharing charts with embedding "EMBEDDABLE_CHARTS": True, "DRILL_TO_DETAIL": False, + "DRILL_BY": False, "DATAPANEL_CLOSED_BY_DEFAULT": False, "HORIZONTAL_FILTER_BAR": False, # The feature is off by default, and currently only supported in Presto and Postgres, From 226b60bc4f789e94880eb1bb0c06667be09e13f9 Mon Sep 17 00:00:00 2001 From: Zef Lin Date: Tue, 21 Mar 2023 09:13:38 -0700 Subject: [PATCH 2/4] fix: safe check when computing chart thumbnail (#23432) --- superset/tasks/thumbnails.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/superset/tasks/thumbnails.py b/superset/tasks/thumbnails.py index d76939a07e3a0..03b3999dce876 100644 --- a/superset/tasks/thumbnails.py +++ b/superset/tasks/thumbnails.py @@ -48,6 +48,9 @@ def cache_chart_thumbnail( logger.warning("No cache set, refusing to compute") return None chart = cast(Slice, Slice.get(chart_id)) + if not chart: + logger.warning("No chart found, skip computing chart thumbnail") + return None url = get_url_path("Superset.slice", slice_id=chart.id) logger.info("Caching chart: %s", url) _, username = get_executor( From d01cf4300cbe54bd9bb210a6ddedfb7a447f0cdf Mon Sep 17 00:00:00 2001 From: Beto Dealmeida Date: Tue, 21 Mar 2023 15:26:11 -0700 Subject: [PATCH 3/4] fix: schedule query option showing up (#23386) Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> --- superset-frontend/src/SqlLab/components/SqlEditor/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx b/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx index 2a93cad2706e9..c19db43089789 100644 --- a/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx +++ b/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx @@ -545,7 +545,7 @@ const SqlEditor = ({ /> )} - {scheduledQueriesConf && ( + {!isEmpty(scheduledQueriesConf) && ( Date: Tue, 21 Mar 2023 15:48:55 -0700 Subject: [PATCH 4/4] fix: prevent ForeignKeyViolation error on delete (#23414) --- superset/charts/commands/delete.py | 7 ++++++- superset/datasets/commands/delete.py | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/superset/charts/commands/delete.py b/superset/charts/commands/delete.py index cb6644c711c45..4c636f0433a73 100644 --- a/superset/charts/commands/delete.py +++ b/superset/charts/commands/delete.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. import logging -from typing import Optional +from typing import cast, Optional from flask_appbuilder.models.sqla import Model from flask_babel import lazy_gettext as _ @@ -45,8 +45,13 @@ def __init__(self, model_id: int): def run(self) -> Model: self.validate() + self._model = cast(Slice, self._model) try: Dashboard.clear_cache_for_slice(slice_id=self._model_id) + # Even though SQLAlchemy should in theory delete rows from the association + # table, sporadically Superset will error because the rows are not deleted. + # Let's do it manually here to prevent the error. + self._model.owners = [] chart = ChartDAO.delete(self._model) except DAODeleteFailedError as ex: logger.exception(ex.exception) diff --git a/superset/datasets/commands/delete.py b/superset/datasets/commands/delete.py index 6f91567958135..1487f1028b3be 100644 --- a/superset/datasets/commands/delete.py +++ b/superset/datasets/commands/delete.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. import logging -from typing import Optional +from typing import cast, Optional from flask_appbuilder.models.sqla import Model from sqlalchemy.exc import SQLAlchemyError @@ -43,7 +43,12 @@ def __init__(self, model_id: int): def run(self) -> Model: self.validate() + self._model = cast(SqlaTable, self._model) try: + # Even though SQLAlchemy should in theory delete rows from the association + # table, sporadically Superset will error because the rows are not deleted. + # Let's do it manually here to prevent the error. + self._model.owners = [] dataset = DatasetDAO.delete(self._model, commit=False) db.session.commit() except (SQLAlchemyError, DAODeleteFailedError) as ex: