mirror of
https://github.com/apache/superset.git
synced 2026-04-20 08:34:37 +00:00
fix: improve get_db_engine_spec_for_backend (#21171)
* fix: improve get_db_engine_spec_for_backend * Fix tests * Fix docs * fix lint * fix fallback * Fix engine validation * Fix test
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
# under the License.
|
||||
import inspect
|
||||
import json
|
||||
from typing import Any, Dict, Optional, Type
|
||||
from typing import Any, Dict
|
||||
|
||||
from flask import current_app
|
||||
from flask_babel import lazy_gettext as _
|
||||
@@ -28,7 +28,7 @@ from sqlalchemy import MetaData
|
||||
from superset import db
|
||||
from superset.databases.commands.exceptions import DatabaseInvalidError
|
||||
from superset.databases.utils import make_url_safe
|
||||
from superset.db_engine_specs import BaseEngineSpec, get_engine_specs
|
||||
from superset.db_engine_specs import get_engine_spec
|
||||
from superset.exceptions import CertificateException, SupersetSecurityException
|
||||
from superset.models.core import ConfigurationMethod, Database, PASSWORD_MASK
|
||||
from superset.security.analytics_db_safety import check_sqlalchemy_uri
|
||||
@@ -150,7 +150,7 @@ def sqlalchemy_uri_validator(value: str) -> str:
|
||||
[
|
||||
_(
|
||||
"Invalid connection string, a valid string usually follows: "
|
||||
"driver://user:password@database-host/database-name"
|
||||
"backend+driver://user:password@database-host/database-name"
|
||||
)
|
||||
]
|
||||
) from ex
|
||||
@@ -231,6 +231,7 @@ class DatabaseParametersSchemaMixin: # pylint: disable=too-few-public-methods
|
||||
"""
|
||||
|
||||
engine = fields.String(allow_none=True, description="SQLAlchemy engine to use")
|
||||
driver = fields.String(allow_none=True, description="SQLAlchemy driver to use")
|
||||
parameters = fields.Dict(
|
||||
keys=fields.String(),
|
||||
values=fields.Raw(),
|
||||
@@ -262,10 +263,20 @@ class DatabaseParametersSchemaMixin: # pylint: disable=too-few-public-methods
|
||||
or parameters.pop("engine", None)
|
||||
or data.pop("backend", None)
|
||||
)
|
||||
driver = data.pop("driver", None)
|
||||
|
||||
configuration_method = data.get("configuration_method")
|
||||
if configuration_method == ConfigurationMethod.DYNAMIC_FORM:
|
||||
engine_spec = get_engine_spec(engine)
|
||||
if not engine:
|
||||
raise ValidationError(
|
||||
[
|
||||
_(
|
||||
"An engine must be specified when passing "
|
||||
"individual parameters to a database."
|
||||
)
|
||||
]
|
||||
)
|
||||
engine_spec = get_engine_spec(engine, driver)
|
||||
|
||||
if not hasattr(engine_spec, "build_sqlalchemy_uri") or not hasattr(
|
||||
engine_spec, "parameters_schema"
|
||||
@@ -295,34 +306,12 @@ class DatabaseParametersSchemaMixin: # pylint: disable=too-few-public-methods
|
||||
return data
|
||||
|
||||
|
||||
def get_engine_spec(engine: Optional[str]) -> Type[BaseEngineSpec]:
|
||||
if not engine:
|
||||
raise ValidationError(
|
||||
[
|
||||
_(
|
||||
"An engine must be specified when passing "
|
||||
"individual parameters to a database."
|
||||
)
|
||||
]
|
||||
)
|
||||
engine_specs = get_engine_specs()
|
||||
if engine not in engine_specs:
|
||||
raise ValidationError(
|
||||
[
|
||||
_(
|
||||
'Engine "%(engine)s" is not a valid engine.',
|
||||
engine=engine,
|
||||
)
|
||||
]
|
||||
)
|
||||
return engine_specs[engine]
|
||||
|
||||
|
||||
class DatabaseValidateParametersSchema(Schema):
|
||||
class Meta: # pylint: disable=too-few-public-methods
|
||||
unknown = EXCLUDE
|
||||
|
||||
engine = fields.String(required=True, description="SQLAlchemy engine to use")
|
||||
driver = fields.String(allow_none=True, description="SQLAlchemy driver to use")
|
||||
parameters = fields.Dict(
|
||||
keys=fields.String(),
|
||||
values=fields.Raw(allow_none=True),
|
||||
|
||||
Reference in New Issue
Block a user