You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by jl...@apache.org on 2025/08/21 21:05:38 UTC

(superset) 02/04: fix: catch no table error (#32640)

This is an automated email from the ASF dual-hosted git repository.

jli pushed a commit to branch 6.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 958b29acbc8045cee4c5a7e90aa085d370dd6914
Author: Elizabeth Thompson <es...@gmail.com>
AuthorDate: Thu Aug 21 10:40:44 2025 -0700

    fix: catch no table error (#32640)
    
    (cherry picked from commit 695a20d0098ba46f5fdd34e8d77e04584af71229)
---
 superset/db_engine_specs/presto.py                 | 45 +++++++++++++---------
 .../db_engine_specs/presto_tests.py                | 23 +++++++++++
 2 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/superset/db_engine_specs/presto.py b/superset/db_engine_specs/presto.py
index c1622b3632..32c82a6af1 100644
--- a/superset/db_engine_specs/presto.py
+++ b/superset/db_engine_specs/presto.py
@@ -38,12 +38,14 @@ from sqlalchemy.engine.base import Engine
 from sqlalchemy.engine.reflection import Inspector
 from sqlalchemy.engine.result import Row as ResultRow
 from sqlalchemy.engine.url import URL
+from sqlalchemy.exc import NoSuchTableError
 from sqlalchemy.sql.expression import ColumnClause, Select
 
 from superset import cache_manager, db, is_feature_enabled
 from superset.common.db_query_status import QueryStatus
 from superset.constants import TimeGrain
 from superset.db_engine_specs.base import BaseEngineSpec
+from superset.db_engine_specs.exceptions import SupersetDBAPIProgrammingError
 from superset.errors import SupersetErrorType
 from superset.exceptions import SupersetTemplateException
 from superset.models.sql_lab import Query
@@ -1250,26 +1252,31 @@ class PrestoEngineSpec(PrestoBaseEngineSpec):
     ) -> dict[str, Any]:
         metadata = {}
 
-        if indexes := database.get_indexes(table):
-            col_names, latest_parts = cls.latest_partition(
-                database,
-                table,
-                show_first=True,
-                indexes=indexes,
-            )
-
-            if not latest_parts:
-                latest_parts = tuple([None] * len(col_names))
-
-            metadata["partitions"] = {
-                "cols": sorted(indexes[0].get("column_names", [])),
-                "latest": dict(zip(col_names, latest_parts, strict=False)),
-                "partitionQuery": cls._partition_query(
-                    table=table,
+        try:
+            if indexes := database.get_indexes(table):
+                col_names, latest_parts = cls.latest_partition(
+                    database,
+                    table,
+                    show_first=True,
                     indexes=indexes,
-                    database=database,
-                ),
-            }
+                )
+
+                if not latest_parts:
+                    latest_parts = tuple([None] * len(col_names))
+
+                metadata["partitions"] = {
+                    "cols": sorted(indexes[0].get("column_names", [])),
+                    "latest": dict(zip(col_names, latest_parts, strict=False)),
+                    "partitionQuery": cls._partition_query(
+                        table=table,
+                        indexes=indexes,
+                        database=database,
+                    ),
+                }
+        except NoSuchTableError as ex:
+            raise SupersetDBAPIProgrammingError(
+                "Table doesn't seem to exist on the database"
+            ) from ex
 
         metadata["view"] = cast(
             Any,
diff --git a/tests/integration_tests/db_engine_specs/presto_tests.py b/tests/integration_tests/db_engine_specs/presto_tests.py
index ca9cff8fce..df12ca5241 100644
--- a/tests/integration_tests/db_engine_specs/presto_tests.py
+++ b/tests/integration_tests/db_engine_specs/presto_tests.py
@@ -19,8 +19,10 @@ from textwrap import dedent
 from unittest import mock, skipUnless
 
 import pandas as pd
+import pytest
 from flask.ctx import AppContext
 from sqlalchemy import types  # noqa: F401
+from sqlalchemy.exc import NoSuchTableError
 from sqlalchemy.sql import select
 
 from superset.db_engine_specs.presto import PrestoEngineSpec
@@ -570,6 +572,27 @@ class TestPrestoDbEngineSpec(SupersetTestCase):
         assert result["partitions"]["cols"] == ["ds", "hour"]
         assert result["partitions"]["latest"] == {"ds": "01-01-19", "hour": 1}
 
+    def test_get_extra_table_metadata_no_table_found(self):
+        """
+        Test get_extra_table_metadata when a NoSuchTableError (simulating NoTableFound)
+        is raised by the database.get_df method.
+        """
+        # Setup a fake database
+        database = mock.MagicMock()
+        database.get_indexes.return_value = [
+            {"column_names": ["ds"]}
+        ]  # Return indexes so get_df is called
+        database.get_extra.return_value = {}
+        # Simulate that the table is not found
+        database.get_df.side_effect = NoSuchTableError("Table not found")
+
+        from superset.db_engine_specs.exceptions import SupersetDBAPIProgrammingError
+
+        with pytest.raises(SupersetDBAPIProgrammingError):
+            PrestoEngineSpec.get_extra_table_metadata(
+                database, Table("test_table", "test_schema")
+            )
+
     def test_presto_where_latest_partition(self):
         db = mock.Mock()
         db.get_indexes = mock.Mock(return_value=[{"column_names": ["ds", "hour"]}])