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:42 UTC
[superset] 01/01: feat: add MotherDuck DB engine spec
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}"