You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by hu...@apache.org on 2022/10/07 17:14:22 UTC

[superset] 13/13: fix conflict with cherry 882bfb67a

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

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

commit 2af1000492999ec4461b816560d975dd5117855b
Author: Hugh A. Miles II <hu...@gmail.com>
AuthorDate: Thu Oct 6 22:57:12 2022 -0400

    fix conflict with cherry 882bfb67a
---
 .../CRUD/data/database/DatabaseModal/index.tsx     | 17 +++++++-
 superset/databases/schemas.py                      |  5 +++
 superset/db_engine_specs/gsheets.py                | 19 +++++++--
 tests/unit_tests/db_engine_specs/test_gsheets.py   | 48 ++++++++++++++++++----
 4 files changed, 76 insertions(+), 13 deletions(-)

diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx
index de5d750ebd..a2ca444752 100644
--- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx
+++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx
@@ -569,6 +569,18 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
     // Clone DB object
     const dbToUpdate = JSON.parse(JSON.stringify(db || {}));
 
+    if (dbToUpdate.catalog) {
+      // convert catalog to fit /validate_parameters endpoint
+      dbToUpdate.catalog = Object.assign(
+        {},
+        ...dbToUpdate.catalog.map((x: { name: string; value: string }) => ({
+          [x.name]: x.value,
+        })),
+      );
+    } else {
+      dbToUpdate.catalog = {};
+    }
+
     if (dbToUpdate.configuration_method === CONFIGURATION_METHOD.DYNAMIC_FORM) {
       // Validate DB before saving
       const errors = await getValidation(dbToUpdate, true);
@@ -734,7 +746,10 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
       });
     }
 
-    setDB({ type: ActionType.addTableCatalogSheet });
+    if (database_name === 'Google Sheets') {
+      // only create a catalog if the DB is Google Sheets
+      setDB({ type: ActionType.addTableCatalogSheet });
+    }
   };
 
   const renderAvailableSelector = () => (
diff --git a/superset/databases/schemas.py b/superset/databases/schemas.py
index 201e35cbfc..dafd1ba7fc 100644
--- a/superset/databases/schemas.py
+++ b/superset/databases/schemas.py
@@ -315,6 +315,11 @@ class DatabaseValidateParametersSchema(Schema):
         values=fields.Raw(allow_none=True),
         description="DB-specific parameters for configuration",
     )
+    catalog = fields.Dict(
+        keys=fields.String(),
+        values=fields.Raw(allow_none=True),
+        description="Gsheets specific column for managing label to sheet urls",
+    )
     database_name = fields.String(
         description=database_name_description,
         allow_none=True,
diff --git a/superset/db_engine_specs/gsheets.py b/superset/db_engine_specs/gsheets.py
index 3562e0d0b1..b42b26c3bc 100644
--- a/superset/db_engine_specs/gsheets.py
+++ b/superset/db_engine_specs/gsheets.py
@@ -55,6 +55,11 @@ class GSheetsParametersSchema(Schema):
 
 class GSheetsParametersType(TypedDict):
     service_account_info: str
+    catalog: Optional[Dict[str, str]]
+
+
+class GSheetsPropertiesType(TypedDict):
+    parameters: GSheetsParametersType
     catalog: Dict[str, str]
 
 
@@ -208,9 +213,18 @@ class GSheetsEngineSpec(SqliteEngineSpec):
     @classmethod
     def validate_parameters(
         cls,
-        parameters: GSheetsParametersType,
+        properties: GSheetsParametersType,
     ) -> List[SupersetError]:
         errors: List[SupersetError] = []
+
+        # backwards compatible just incase people are send data
+        # via parameters for validation
+        parameters = properties.get("parameters", {})
+        if parameters and parameters.get("catalog"):
+            table_catalog = parameters.get("catalog", {})
+        else:
+            table_catalog = properties.get("catalog", {})
+
         encrypted_credentials = parameters.get("service_account_info") or "{}"
 
         # On create the encrypted credentials are a string,
@@ -218,8 +232,6 @@ class GSheetsEngineSpec(SqliteEngineSpec):
         if isinstance(encrypted_credentials, str):
             encrypted_credentials = json.loads(encrypted_credentials)
 
-        table_catalog = parameters.get("catalog", {})
-
         if not table_catalog:
             # Allowing users to submit empty catalogs
             errors.append(
@@ -245,6 +257,7 @@ class GSheetsEngineSpec(SqliteEngineSpec):
         )
         conn = engine.connect()
         idx = 0
+
         for name, url in table_catalog.items():
 
             if not name:
diff --git a/tests/unit_tests/db_engine_specs/test_gsheets.py b/tests/unit_tests/db_engine_specs/test_gsheets.py
index a226653ed5..4a0092b4f7 100644
--- a/tests/unit_tests/db_engine_specs/test_gsheets.py
+++ b/tests/unit_tests/db_engine_specs/test_gsheets.py
@@ -33,11 +33,38 @@ class ProgrammingError(Exception):
 def test_validate_parameters_simple() -> None:
     from superset.db_engine_specs.gsheets import (
         GSheetsEngineSpec,
-        GSheetsParametersType,
+        GSheetsPropertiesType,
     )
 
-    parameters: GSheetsParametersType = {
-        "service_account_info": "",
+    properties: GSheetsPropertiesType = {
+        "parameters": {
+            "service_account_info": "",
+            "catalog": {},
+        },
+        "catalog": {},
+    }
+    errors = GSheetsEngineSpec.validate_parameters(properties)
+    assert errors == [
+        SupersetError(
+            message="Sheet name is required",
+            error_type=SupersetErrorType.CONNECTION_MISSING_PARAMETERS_ERROR,
+            level=ErrorLevel.WARNING,
+            extra={"catalog": {"idx": 0, "name": True}},
+        ),
+    ]
+
+
+def test_validate_parameters_simple_with_in_root_catalog() -> None:
+    from superset.db_engine_specs.gsheets import (
+        GSheetsEngineSpec,
+        GSheetsPropertiesType,
+    )
+
+    properties: GSheetsPropertiesType = {
+        "parameters": {
+            "service_account_info": "",
+            "catalog": {},
+        },
         "catalog": {},
     }
     errors = GSheetsEngineSpec.validate_parameters(parameters)
@@ -56,7 +83,7 @@ def test_validate_parameters_catalog(
 ) -> None:
     from superset.db_engine_specs.gsheets import (
         GSheetsEngineSpec,
-        GSheetsParametersType,
+        GSheetsPropertiesType,
     )
 
     g = mocker.patch("superset.db_engine_specs.gsheets.g")
@@ -71,8 +98,8 @@ def test_validate_parameters_catalog(
         ProgrammingError("Unsupported table: https://www.google.com/"),
     ]
 
-    parameters: GSheetsParametersType = {
-        "service_account_info": "",
+    properties: GSheetsPropertiesType = {
+        "parameters": {"service_account_info": "", "catalog": None},
         "catalog": {
             "private_sheet": "https://docs.google.com/spreadsheets/d/1/edit",
             "public_sheet": "https://docs.google.com/spreadsheets/d/1/edit#gid=1",
@@ -146,7 +173,7 @@ def test_validate_parameters_catalog_and_credentials(
 ) -> None:
     from superset.db_engine_specs.gsheets import (
         GSheetsEngineSpec,
-        GSheetsParametersType,
+        GSheetsPropertiesType,
     )
 
     g = mocker.patch("superset.db_engine_specs.gsheets.g")
@@ -161,8 +188,11 @@ def test_validate_parameters_catalog_and_credentials(
         ProgrammingError("Unsupported table: https://www.google.com/"),
     ]
 
-    parameters: GSheetsParametersType = {
-        "service_account_info": "",
+    properties: GSheetsPropertiesType = {
+        "parameters": {
+            "service_account_info": "",
+            "catalog": None,
+        },
         "catalog": {
             "private_sheet": "https://docs.google.com/spreadsheets/d/1/edit",
             "public_sheet": "https://docs.google.com/spreadsheets/d/1/edit#gid=1",