You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by be...@apache.org on 2023/08/09 15:45:41 UTC

[superset] branch add_motherduck created (now 6676aff363)

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

beto pushed a change to branch add_motherduck
in repository https://gitbox.apache.org/repos/asf/superset.git


      at 6676aff363 feat: add MotherDuck DB engine spec

This branch includes the following new commits:

     new 6676aff363 feat: add MotherDuck DB engine spec

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[superset] 01/01: feat: add MotherDuck DB engine spec

Posted by be...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 6676aff363f577673bb8648de2d82477acf9046d
Author: Beto Dealmeida <ro...@dealmeida.net>
AuthorDate: Wed Aug 9 08:44:45 2023 -0700

    feat: add MotherDuck DB engine spec
---
 setup.py                                           |  1 +
 .../databases/DatabaseModal/SqlAlchemyForm.tsx     | 27 +++++++++++-----------
 .../src/features/databases/DatabaseModal/index.tsx | 10 ++++++--
 superset/databases/api.py                          |  4 ++++
 superset/db_engine_specs/base.py                   | 11 +++++----
 superset/db_engine_specs/duckdb.py                 |  7 ++++++
 6 files changed, 39 insertions(+), 21 deletions(-)

diff --git a/setup.py b/setup.py
index b3f225bce5..2f1a900754 100644
--- a/setup.py
+++ b/setup.py
@@ -150,6 +150,7 @@ setup(
         "dremio": ["sqlalchemy-dremio>=1.1.5, <1.3"],
         "drill": ["sqlalchemy-drill==0.1.dev"],
         "druid": ["pydruid>=0.6.5,<0.7"],
+        "duckdb": ["duckdb-engine==0.8.0"],
         "dynamodb": ["pydynamodb>=0.4.2"],
         "solr": ["sqlalchemy-solr >= 0.2.0"],
         "elasticsearch": ["elasticsearch-dbapi>=0.2.9, <0.3.0"],
diff --git a/superset-frontend/src/features/databases/DatabaseModal/SqlAlchemyForm.tsx b/superset-frontend/src/features/databases/DatabaseModal/SqlAlchemyForm.tsx
index 5d50625cdd..0223da867a 100644
--- a/superset-frontend/src/features/databases/DatabaseModal/SqlAlchemyForm.tsx
+++ b/superset-frontend/src/features/databases/DatabaseModal/SqlAlchemyForm.tsx
@@ -38,17 +38,15 @@ const SqlAlchemyTab = ({
   testInProgress?: boolean;
   children?: ReactNode;
 }) => {
-  let fallbackDocsUrl;
-  let fallbackDisplayText;
-  if (SupersetText) {
-    fallbackDocsUrl =
-      SupersetText.DB_MODAL_SQLALCHEMY_FORM?.SQLALCHEMY_DOCS_URL;
-    fallbackDisplayText =
-      SupersetText.DB_MODAL_SQLALCHEMY_FORM?.SQLALCHEMY_DISPLAY_TEXT;
-  } else {
-    fallbackDocsUrl = 'https://docs.sqlalchemy.org/en/13/core/engines.html';
-    fallbackDisplayText = 'SQLAlchemy docs';
-  }
+  const fallbackDocsUrl =
+    SupersetText?.DB_MODAL_SQLALCHEMY_FORM?.SQLALCHEMY_DOCS_URL ||
+    'https://docs.sqlalchemy.org/en/13/core/engines.html';
+  const fallbackDisplayText =
+    SupersetText?.DB_MODAL_SQLALCHEMY_FORM?.SQLALCHEMY_DISPLAY_TEXT ||
+    'SQLAlchemy docs';
+
+  console.log(db);
+
   return (
     <>
       <StyledInputContainer>
@@ -82,9 +80,10 @@ const SqlAlchemyTab = ({
             data-test="sqlalchemy-uri-input"
             value={db?.sqlalchemy_uri || ''}
             autoComplete="off"
-            placeholder={t(
-              'dialect+driver://username:password@host:port/database',
-            )}
+            placeholder={
+              db?.sqlalchemy_uri_placeholder ||
+              t('dialect+driver://username:password@host:port/database')
+            }
             onChange={onInputChange}
           />
         </div>
diff --git a/superset-frontend/src/features/databases/DatabaseModal/index.tsx b/superset-frontend/src/features/databases/DatabaseModal/index.tsx
index dd2e405350..0823b21e01 100644
--- a/superset-frontend/src/features/databases/DatabaseModal/index.tsx
+++ b/superset-frontend/src/features/databases/DatabaseModal/index.tsx
@@ -946,8 +946,13 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
       const selectedDbModel = availableDbs?.databases.filter(
         (db: DatabaseObject) => db.name === database_name,
       )[0];
-      const { engine, parameters, engine_information, default_driver } =
-        selectedDbModel;
+      const {
+        engine,
+        parameters,
+        engine_information,
+        default_driver,
+        sqlalchemy_uri_placeholder,
+      } = selectedDbModel;
       const isDynamic = parameters !== undefined;
       setDB({
         type: ActionType.dbSelected,
@@ -959,6 +964,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
             : CONFIGURATION_METHOD.SQLALCHEMY_URI,
           engine_information,
           driver: default_driver,
+          sqlalchemy_uri_placeholder,
         },
       });
 
diff --git a/superset/databases/api.py b/superset/databases/api.py
index ae9cd60188..116e2ddb1f 100644
--- a/superset/databases/api.py
+++ b/superset/databases/api.py
@@ -1293,6 +1293,9 @@ class DatabaseRestApi(BaseSupersetModelRestApi):
                           type: array
                           items:
                             type: string
+                        sqlalchemy_uri_placeholder:
+                          description: Placeholder for the SQLAlchemy URI
+                          type: string
                         default_driver:
                           description: Default driver for the engine
                           type: string
@@ -1330,6 +1333,7 @@ class DatabaseRestApi(BaseSupersetModelRestApi):
                 "name": engine_spec.engine_name,
                 "engine": engine_spec.engine,
                 "available_drivers": sorted(drivers),
+                "sqlalchemy_uri_placeholder": engine_spec.sqlalchemy_uri_placeholder,
                 "preferred": engine_spec.engine_name in preferred_databases,
                 "engine_information": engine_spec.get_public_information(),
             }
diff --git a/superset/db_engine_specs/base.py b/superset/db_engine_specs/base.py
index 2e1d5598ff..d3ffce018a 100644
--- a/superset/db_engine_specs/base.py
+++ b/superset/db_engine_specs/base.py
@@ -185,6 +185,12 @@ class BaseEngineSpec:  # pylint: disable=too-many-public-methods
     engine_aliases: set[str] = set()
     drivers: dict[str, str] = {}
     default_driver: str | None = None
+
+    # placeholder with the SQLAlchemy URI template
+    sqlalchemy_uri_placeholder = (
+        "engine+driver://user:password@host:port/dbname[?key=value&key=value...]"
+    )
+
     disable_ssh_tunneling = False
 
     _date_trunc_functions: dict[str, str] = {}
@@ -1958,11 +1964,6 @@ class BasicParametersMixin:
     # recommended driver name for the DB engine spec
     default_driver = ""
 
-    # placeholder with the SQLAlchemy URI template
-    sqlalchemy_uri_placeholder = (
-        "engine+driver://user:password@host:port/dbname[?key=value&key=value...]"
-    )
-
     # query parameter to enable encryption in the database connection
     # for Postgres this would be `{"sslmode": "verify-ca"}`, eg.
     encryption_parameters: dict[str, str] = {}
diff --git a/superset/db_engine_specs/duckdb.py b/superset/db_engine_specs/duckdb.py
index fa2f01f50a..291b5521ef 100644
--- a/superset/db_engine_specs/duckdb.py
+++ b/superset/db_engine_specs/duckdb.py
@@ -80,3 +80,10 @@ class DuckDBEngineSpec(BaseEngineSpec):
         cls, database: Database, inspector: Inspector, schema: str | None
     ) -> set[str]:
         return set(inspector.get_table_names(schema))
+
+
+class MotherDuckEngineSpec(DuckDBEngineSpec):
+    engine = "duckdb"
+    engine_name = "MotherDuck"
+
+    sqlalchemy_uri_placeholder = "duckdb:///md:{SERVICE_TOKEN}@{database_name}"