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:48:12 UTC

[superset] branch add_motherduck updated (6676aff363 -> 7c0b0b6d0f)

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


 discard 6676aff363 feat: add MotherDuck DB engine spec
     new 7c0b0b6d0f feat: add MotherDuck DB engine spec

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (6676aff363)
            \
             N -- N -- N   refs/heads/add_motherduck (7c0b0b6d0f)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

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.


Summary of changes:
 .../src/features/databases/DatabaseModal/SqlAlchemyForm.tsx             | 2 --
 1 file changed, 2 deletions(-)


[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 7c0b0b6d0ff59e3208287e5887cbdc20c945b448
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     | 25 ++++++++++------------
 .../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, 37 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..0dd4cd97d0 100644
--- a/superset-frontend/src/features/databases/DatabaseModal/SqlAlchemyForm.tsx
+++ b/superset-frontend/src/features/databases/DatabaseModal/SqlAlchemyForm.tsx
@@ -38,17 +38,13 @@ 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';
+
   return (
     <>
       <StyledInputContainer>
@@ -82,9 +78,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}"