diff --git a/superset/annotation_layers/annotations/commands/bulk_delete.py b/superset/annotation_layers/annotations/commands/bulk_delete.py index dd47047788..2e0c53808f 100644 --- a/superset/annotation_layers/annotations/commands/bulk_delete.py +++ b/superset/annotation_layers/annotations/commands/bulk_delete.py @@ -21,9 +21,9 @@ from superset.annotation_layers.annotations.commands.exceptions import ( AnnotationBulkDeleteFailedError, AnnotationNotFoundError, ) -from superset.annotation_layers.annotations.dao import AnnotationDAO from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.annotation import AnnotationDAO +from superset.daos.exceptions import DAODeleteFailedError from superset.models.annotations import Annotation logger = logging.getLogger(__name__) diff --git a/superset/annotation_layers/annotations/commands/create.py b/superset/annotation_layers/annotations/commands/create.py index 986b564291..ed4e76cee6 100644 --- a/superset/annotation_layers/annotations/commands/create.py +++ b/superset/annotation_layers/annotations/commands/create.py @@ -27,11 +27,10 @@ from superset.annotation_layers.annotations.commands.exceptions import ( AnnotationInvalidError, AnnotationUniquenessValidationError, ) -from superset.annotation_layers.annotations.dao import AnnotationDAO from superset.annotation_layers.commands.exceptions import AnnotationLayerNotFoundError -from superset.annotation_layers.dao import AnnotationLayerDAO from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAOCreateFailedError +from superset.daos.annotation import AnnotationDAO, AnnotationLayerDAO +from superset.daos.exceptions import DAOCreateFailedError logger = logging.getLogger(__name__) diff --git a/superset/annotation_layers/annotations/commands/delete.py b/superset/annotation_layers/annotations/commands/delete.py index 915f7f80ce..b86ae997a4 100644 --- a/superset/annotation_layers/annotations/commands/delete.py +++ b/superset/annotation_layers/annotations/commands/delete.py @@ -23,9 +23,9 @@ from superset.annotation_layers.annotations.commands.exceptions import ( AnnotationDeleteFailedError, AnnotationNotFoundError, ) -from superset.annotation_layers.annotations.dao import AnnotationDAO from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.annotation import AnnotationDAO +from superset.daos.exceptions import DAODeleteFailedError from superset.models.annotations import Annotation logger = logging.getLogger(__name__) diff --git a/superset/annotation_layers/annotations/commands/update.py b/superset/annotation_layers/annotations/commands/update.py index 99ab209165..03797a555b 100644 --- a/superset/annotation_layers/annotations/commands/update.py +++ b/superset/annotation_layers/annotations/commands/update.py @@ -28,11 +28,10 @@ from superset.annotation_layers.annotations.commands.exceptions import ( AnnotationUniquenessValidationError, AnnotationUpdateFailedError, ) -from superset.annotation_layers.annotations.dao import AnnotationDAO from superset.annotation_layers.commands.exceptions import AnnotationLayerNotFoundError -from superset.annotation_layers.dao import AnnotationLayerDAO from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAOUpdateFailedError +from superset.daos.annotation import AnnotationDAO, AnnotationLayerDAO +from superset.daos.exceptions import DAOUpdateFailedError from superset.models.annotations import Annotation logger = logging.getLogger(__name__) diff --git a/superset/annotation_layers/annotations/dao.py b/superset/annotation_layers/annotations/dao.py deleted file mode 100644 index da69e576e5..0000000000 --- a/superset/annotation_layers/annotations/dao.py +++ /dev/null @@ -1,64 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -import logging -from typing import Optional - -from sqlalchemy.exc import SQLAlchemyError - -from superset.dao.base import BaseDAO -from superset.dao.exceptions import DAODeleteFailedError -from superset.extensions import db -from superset.models.annotations import Annotation - -logger = logging.getLogger(__name__) - - -class AnnotationDAO(BaseDAO): - model_cls = Annotation - - @staticmethod - def bulk_delete(models: Optional[list[Annotation]], commit: bool = True) -> None: - item_ids = [model.id for model in models] if models else [] - try: - db.session.query(Annotation).filter(Annotation.id.in_(item_ids)).delete( - synchronize_session="fetch" - ) - if commit: - db.session.commit() - except SQLAlchemyError as ex: - db.session.rollback() - raise DAODeleteFailedError() from ex - - @staticmethod - def validate_update_uniqueness( - layer_id: int, short_descr: str, annotation_id: Optional[int] = None - ) -> bool: - """ - Validate if this annotation short description is unique. `id` is optional - and serves for validating on updates - - :param short_descr: The annotation short description - :param layer_id: The annotation layer current id - :param annotation_id: This annotation is (only for validating on updates) - :return: bool - """ - query = db.session.query(Annotation).filter( - Annotation.short_descr == short_descr, Annotation.layer_id == layer_id - ) - if annotation_id: - query = query.filter(Annotation.id != annotation_id) - return not db.session.query(query.exists()).scalar() diff --git a/superset/annotation_layers/commands/bulk_delete.py b/superset/annotation_layers/commands/bulk_delete.py index 4910dc4275..e4696065a6 100644 --- a/superset/annotation_layers/commands/bulk_delete.py +++ b/superset/annotation_layers/commands/bulk_delete.py @@ -22,9 +22,9 @@ from superset.annotation_layers.commands.exceptions import ( AnnotationLayerBulkDeleteIntegrityError, AnnotationLayerNotFoundError, ) -from superset.annotation_layers.dao import AnnotationLayerDAO from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.annotation import AnnotationLayerDAO +from superset.daos.exceptions import DAODeleteFailedError from superset.models.annotations import AnnotationLayer logger = logging.getLogger(__name__) diff --git a/superset/annotation_layers/commands/create.py b/superset/annotation_layers/commands/create.py index 86b0cb3b85..08ef4ad10d 100644 --- a/superset/annotation_layers/commands/create.py +++ b/superset/annotation_layers/commands/create.py @@ -25,9 +25,9 @@ from superset.annotation_layers.commands.exceptions import ( AnnotationLayerInvalidError, AnnotationLayerNameUniquenessValidationError, ) -from superset.annotation_layers.dao import AnnotationLayerDAO from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAOCreateFailedError +from superset.daos.annotation import AnnotationLayerDAO +from superset.daos.exceptions import DAOCreateFailedError logger = logging.getLogger(__name__) diff --git a/superset/annotation_layers/commands/delete.py b/superset/annotation_layers/commands/delete.py index 3dbd7a574f..0692d4dd83 100644 --- a/superset/annotation_layers/commands/delete.py +++ b/superset/annotation_layers/commands/delete.py @@ -24,9 +24,9 @@ from superset.annotation_layers.commands.exceptions import ( AnnotationLayerDeleteIntegrityError, AnnotationLayerNotFoundError, ) -from superset.annotation_layers.dao import AnnotationLayerDAO from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.annotation import AnnotationLayerDAO +from superset.daos.exceptions import DAODeleteFailedError from superset.models.annotations import AnnotationLayer logger = logging.getLogger(__name__) diff --git a/superset/annotation_layers/commands/update.py b/superset/annotation_layers/commands/update.py index 67d869c005..ca3a288413 100644 --- a/superset/annotation_layers/commands/update.py +++ b/superset/annotation_layers/commands/update.py @@ -26,9 +26,9 @@ from superset.annotation_layers.commands.exceptions import ( AnnotationLayerNotFoundError, AnnotationLayerUpdateFailedError, ) -from superset.annotation_layers.dao import AnnotationLayerDAO from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAOUpdateFailedError +from superset.daos.annotation import AnnotationLayerDAO +from superset.daos.exceptions import DAOUpdateFailedError from superset.models.annotations import AnnotationLayer logger = logging.getLogger(__name__) diff --git a/superset/charts/api.py b/superset/charts/api.py index b52ccf84bd..39b0c2dbf8 100644 --- a/superset/charts/api.py +++ b/superset/charts/api.py @@ -47,7 +47,6 @@ from superset.charts.commands.exceptions import ( from superset.charts.commands.export import ExportChartsCommand from superset.charts.commands.importers.dispatcher import ImportChartsCommand from superset.charts.commands.update import UpdateChartCommand -from superset.charts.dao import ChartDAO from superset.charts.filters import ( ChartAllTextFilter, ChartCertifiedFilter, @@ -75,6 +74,7 @@ from superset.commands.importers.exceptions import ( ) from superset.commands.importers.v1.utils import get_contents_from_bundle from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod +from superset.daos.chart import ChartDAO from superset.extensions import event_logger from superset.models.slice import Slice from superset.tasks.thumbnails import cache_chart_thumbnail diff --git a/superset/charts/commands/bulk_delete.py b/superset/charts/commands/bulk_delete.py index ac801b7421..964c40d812 100644 --- a/superset/charts/commands/bulk_delete.py +++ b/superset/charts/commands/bulk_delete.py @@ -26,12 +26,12 @@ from superset.charts.commands.exceptions import ( ChartForbiddenError, ChartNotFoundError, ) -from superset.charts.dao import ChartDAO from superset.commands.base import BaseCommand from superset.commands.exceptions import DeleteFailedError +from superset.daos.chart import ChartDAO +from superset.daos.report import ReportScheduleDAO from superset.exceptions import SupersetSecurityException from superset.models.slice import Slice -from superset.reports.dao import ReportScheduleDAO logger = logging.getLogger(__name__) diff --git a/superset/charts/commands/create.py b/superset/charts/commands/create.py index 78706b3a66..3eb0001bb9 100644 --- a/superset/charts/commands/create.py +++ b/superset/charts/commands/create.py @@ -27,11 +27,11 @@ from superset.charts.commands.exceptions import ( ChartInvalidError, DashboardsNotFoundValidationError, ) -from superset.charts.dao import ChartDAO from superset.commands.base import BaseCommand, CreateMixin from superset.commands.utils import get_datasource_by_id -from superset.dao.exceptions import DAOCreateFailedError -from superset.dashboards.dao import DashboardDAO +from superset.daos.chart import ChartDAO +from superset.daos.dashboard import DashboardDAO +from superset.daos.exceptions import DAOCreateFailedError logger = logging.getLogger(__name__) diff --git a/superset/charts/commands/delete.py b/superset/charts/commands/delete.py index 11f6e59257..184e9f8e1a 100644 --- a/superset/charts/commands/delete.py +++ b/superset/charts/commands/delete.py @@ -27,13 +27,13 @@ from superset.charts.commands.exceptions import ( ChartForbiddenError, ChartNotFoundError, ) -from superset.charts.dao import ChartDAO from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.chart import ChartDAO +from superset.daos.exceptions import DAODeleteFailedError +from superset.daos.report import ReportScheduleDAO from superset.exceptions import SupersetSecurityException from superset.models.dashboard import Dashboard from superset.models.slice import Slice -from superset.reports.dao import ReportScheduleDAO logger = logging.getLogger(__name__) diff --git a/superset/charts/commands/export.py b/superset/charts/commands/export.py index 22310ade99..d1183a999c 100644 --- a/superset/charts/commands/export.py +++ b/superset/charts/commands/export.py @@ -23,7 +23,7 @@ from collections.abc import Iterator import yaml from superset.charts.commands.exceptions import ChartNotFoundError -from superset.charts.dao import ChartDAO +from superset.daos.chart import ChartDAO from superset.datasets.commands.export import ExportDatasetsCommand from superset.commands.export.models import ExportModelsCommand from superset.models.slice import Slice diff --git a/superset/charts/commands/importers/v1/__init__.py b/superset/charts/commands/importers/v1/__init__.py index 132df21b08..2a9c691159 100644 --- a/superset/charts/commands/importers/v1/__init__.py +++ b/superset/charts/commands/importers/v1/__init__.py @@ -22,10 +22,10 @@ from sqlalchemy.orm import Session from superset.charts.commands.exceptions import ChartImportError from superset.charts.commands.importers.v1.utils import import_chart -from superset.charts.dao import ChartDAO from superset.charts.schemas import ImportV1ChartSchema from superset.commands.importers.v1 import ImportModelsCommand from superset.connectors.sqla.models import SqlaTable +from superset.daos.chart import ChartDAO from superset.databases.commands.importers.v1.utils import import_database from superset.databases.schemas import ImportV1DatabaseSchema from superset.datasets.commands.importers.v1.utils import import_dataset diff --git a/superset/charts/commands/update.py b/superset/charts/commands/update.py index a4265d0835..9a5b4e1f29 100644 --- a/superset/charts/commands/update.py +++ b/superset/charts/commands/update.py @@ -31,11 +31,11 @@ from superset.charts.commands.exceptions import ( DashboardsNotFoundValidationError, DatasourceTypeUpdateRequiredValidationError, ) -from superset.charts.dao import ChartDAO from superset.commands.base import BaseCommand, UpdateMixin from superset.commands.utils import get_datasource_by_id -from superset.dao.exceptions import DAOUpdateFailedError -from superset.dashboards.dao import DashboardDAO +from superset.daos.chart import ChartDAO +from superset.daos.dashboard import DashboardDAO +from superset.daos.exceptions import DAOUpdateFailedError from superset.exceptions import SupersetSecurityException from superset.models.slice import Slice diff --git a/superset/charts/data/api.py b/superset/charts/data/api.py index 552044ebfa..effad0e010 100644 --- a/superset/charts/data/api.py +++ b/superset/charts/data/api.py @@ -41,7 +41,7 @@ from superset.charts.post_processing import apply_post_process from superset.charts.schemas import ChartDataQueryContextSchema from superset.common.chart_data import ChartDataResultFormat, ChartDataResultType from superset.connectors.base.models import BaseDatasource -from superset.dao.exceptions import DatasourceNotFound +from superset.daos.exceptions import DatasourceNotFound from superset.exceptions import QueryObjectValidationError from superset.extensions import event_logger from superset.models.sql_lab import Query diff --git a/superset/commands/export/models.py b/superset/commands/export/models.py index 3f21f29281..27f4572af3 100644 --- a/superset/commands/export/models.py +++ b/superset/commands/export/models.py @@ -23,7 +23,7 @@ from flask_appbuilder import Model from superset.commands.base import BaseCommand from superset.commands.exceptions import CommandException -from superset.dao.base import BaseDAO +from superset.daos.base import BaseDAO from superset.utils.dict_import_export import EXPORT_VERSION METADATA_FILE_NAME = "metadata.yaml" diff --git a/superset/commands/importers/v1/__init__.py b/superset/commands/importers/v1/__init__.py index 09830bf3cf..38d6568af4 100644 --- a/superset/commands/importers/v1/__init__.py +++ b/superset/commands/importers/v1/__init__.py @@ -30,7 +30,7 @@ from superset.commands.importers.v1.utils import ( METADATA_FILE_NAME, validate_metadata_type, ) -from superset.dao.base import BaseDAO +from superset.daos.base import BaseDAO from superset.models.core import Database diff --git a/superset/commands/importers/v1/examples.py b/superset/commands/importers/v1/examples.py index 4c20e93ff7..501e993e96 100644 --- a/superset/commands/importers/v1/examples.py +++ b/superset/commands/importers/v1/examples.py @@ -27,7 +27,7 @@ from superset.charts.commands.importers.v1.utils import import_chart from superset.charts.schemas import ImportV1ChartSchema from superset.commands.exceptions import CommandException from superset.commands.importers.v1 import ImportModelsCommand -from superset.dao.base import BaseDAO +from superset.daos.base import BaseDAO from superset.dashboards.commands.importers.v1 import ImportDashboardsCommand from superset.dashboards.commands.importers.v1.utils import ( find_chart_uuids, diff --git a/superset/commands/utils.py b/superset/commands/utils.py index 7bb13984f8..02b6b5f383 100644 --- a/superset/commands/utils.py +++ b/superset/commands/utils.py @@ -27,8 +27,8 @@ from superset.commands.exceptions import ( OwnersNotFoundValidationError, RolesNotFoundValidationError, ) -from superset.dao.exceptions import DatasourceNotFound -from superset.datasource.dao import DatasourceDAO +from superset.daos.datasource import DatasourceDAO +from superset.daos.exceptions import DatasourceNotFound from superset.extensions import db from superset.utils.core import DatasourceType, get_user_id diff --git a/superset/common/query_context_factory.py b/superset/common/query_context_factory.py index 62018def8d..a6fe549894 100644 --- a/superset/common/query_context_factory.py +++ b/superset/common/query_context_factory.py @@ -19,12 +19,12 @@ from __future__ import annotations from typing import Any, TYPE_CHECKING from superset import app, db -from superset.charts.dao import ChartDAO from superset.common.chart_data import ChartDataResultFormat, ChartDataResultType from superset.common.query_context import QueryContext from superset.common.query_object import QueryObject from superset.common.query_object_factory import QueryObjectFactory -from superset.datasource.dao import DatasourceDAO +from superset.daos.chart import ChartDAO +from superset.daos.datasource import DatasourceDAO from superset.models.slice import Slice from superset.utils.core import DatasourceDict, DatasourceType diff --git a/superset/common/query_context_processor.py b/superset/common/query_context_processor.py index 6553c19807..58e9022736 100644 --- a/superset/common/query_context_processor.py +++ b/superset/common/query_context_processor.py @@ -28,8 +28,6 @@ from pandas import DateOffset from typing_extensions import TypedDict from superset import app -from superset.annotation_layers.dao import AnnotationLayerDAO -from superset.charts.dao import ChartDAO from superset.common.chart_data import ChartDataResultFormat from superset.common.db_query_status import QueryStatus from superset.common.query_actions import get_query_results @@ -38,6 +36,8 @@ from superset.common.utils.query_cache_manager import QueryCacheManager from superset.common.utils.time_range_utils import get_since_until_from_query_object from superset.connectors.base.models import BaseDatasource from superset.constants import CacheRegion, TimeGrain +from superset.daos.annotation import AnnotationLayerDAO +from superset.daos.chart import ChartDAO from superset.exceptions import ( InvalidPostProcessingError, QueryObjectValidationError, diff --git a/superset/common/query_object_factory.py b/superset/common/query_object_factory.py index 5676dc9eda..ae85912cdf 100644 --- a/superset/common/query_object_factory.py +++ b/superset/common/query_object_factory.py @@ -27,7 +27,7 @@ if TYPE_CHECKING: from sqlalchemy.orm import sessionmaker from superset.connectors.base.models import BaseDatasource - from superset.datasource.dao import DatasourceDAO + from superset.daos.datasource import DatasourceDAO class QueryObjectFactory: # pylint: disable=too-few-public-methods diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py index ad3ba6f19b..c44b79062b 100644 --- a/superset/connectors/sqla/models.py +++ b/superset/connectors/sqla/models.py @@ -1439,8 +1439,8 @@ class SqlaTable( """ # pylint: disable=import-outside-toplevel + from superset.daos.dataset import DatasetDAO from superset.datasets.commands.exceptions import get_dataset_exist_error_msg - from superset.datasets.dao import DatasetDAO # Check whether the relevant attributes have changed. state = db.inspect(target) # pylint: disable=no-member diff --git a/superset/css_templates/commands/bulk_delete.py b/superset/css_templates/commands/bulk_delete.py index 57612d9048..c676e9eed8 100644 --- a/superset/css_templates/commands/bulk_delete.py +++ b/superset/css_templates/commands/bulk_delete.py @@ -22,8 +22,8 @@ from superset.css_templates.commands.exceptions import ( CssTemplateBulkDeleteFailedError, CssTemplateNotFoundError, ) -from superset.css_templates.dao import CssTemplateDAO -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.css import CssTemplateDAO +from superset.daos.exceptions import DAODeleteFailedError from superset.models.core import CssTemplate logger = logging.getLogger(__name__) diff --git a/superset/dao/__init__.py b/superset/daos/__init__.py similarity index 100% rename from superset/dao/__init__.py rename to superset/daos/__init__.py diff --git a/superset/annotation_layers/dao.py b/superset/daos/annotation.py similarity index 65% rename from superset/annotation_layers/dao.py rename to superset/daos/annotation.py index 67efc19f88..171a708fa4 100644 --- a/superset/annotation_layers/dao.py +++ b/superset/daos/annotation.py @@ -19,14 +19,51 @@ from typing import Optional, Union from sqlalchemy.exc import SQLAlchemyError -from superset.dao.base import BaseDAO -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.base import BaseDAO +from superset.daos.exceptions import DAODeleteFailedError from superset.extensions import db from superset.models.annotations import Annotation, AnnotationLayer logger = logging.getLogger(__name__) +class AnnotationDAO(BaseDAO): + model_cls = Annotation + + @staticmethod + def bulk_delete(models: Optional[list[Annotation]], commit: bool = True) -> None: + item_ids = [model.id for model in models] if models else [] + try: + db.session.query(Annotation).filter(Annotation.id.in_(item_ids)).delete( + synchronize_session="fetch" + ) + if commit: + db.session.commit() + except SQLAlchemyError as ex: + db.session.rollback() + raise DAODeleteFailedError() from ex + + @staticmethod + def validate_update_uniqueness( + layer_id: int, short_descr: str, annotation_id: Optional[int] = None + ) -> bool: + """ + Validate if this annotation short description is unique. `id` is optional + and serves for validating on updates + + :param short_descr: The annotation short description + :param layer_id: The annotation layer current id + :param annotation_id: This annotation is (only for validating on updates) + :return: bool + """ + query = db.session.query(Annotation).filter( + Annotation.short_descr == short_descr, Annotation.layer_id == layer_id + ) + if annotation_id: + query = query.filter(Annotation.id != annotation_id) + return not db.session.query(query.exists()).scalar() + + class AnnotationLayerDAO(BaseDAO): model_cls = AnnotationLayer diff --git a/superset/dao/base.py b/superset/daos/base.py similarity index 99% rename from superset/dao/base.py rename to superset/daos/base.py index 539dbab2d5..6465e5b177 100644 --- a/superset/dao/base.py +++ b/superset/daos/base.py @@ -23,7 +23,7 @@ from flask_appbuilder.models.sqla.interface import SQLAInterface from sqlalchemy.exc import SQLAlchemyError, StatementError from sqlalchemy.orm import Session -from superset.dao.exceptions import ( +from superset.daos.exceptions import ( DAOConfigError, DAOCreateFailedError, DAODeleteFailedError, diff --git a/superset/charts/dao.py b/superset/daos/chart.py similarity index 98% rename from superset/charts/dao.py rename to superset/daos/chart.py index 9c6b2c26ef..838d93abdf 100644 --- a/superset/charts/dao.py +++ b/superset/daos/chart.py @@ -22,7 +22,7 @@ from typing import Optional, TYPE_CHECKING from sqlalchemy.exc import SQLAlchemyError from superset.charts.filters import ChartFilter -from superset.dao.base import BaseDAO +from superset.daos.base import BaseDAO from superset.extensions import db from superset.models.core import FavStar, FavStarClassName from superset.models.slice import Slice diff --git a/superset/css_templates/dao.py b/superset/daos/css.py similarity index 94% rename from superset/css_templates/dao.py rename to superset/daos/css.py index bc1a796269..224277a40a 100644 --- a/superset/css_templates/dao.py +++ b/superset/daos/css.py @@ -19,8 +19,8 @@ from typing import Optional from sqlalchemy.exc import SQLAlchemyError -from superset.dao.base import BaseDAO -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.base import BaseDAO +from superset.daos.exceptions import DAODeleteFailedError from superset.extensions import db from superset.models.core import CssTemplate diff --git a/superset/dashboards/dao.py b/superset/daos/dashboard.py similarity index 84% rename from superset/dashboards/dao.py rename to superset/daos/dashboard.py index 9de94f9493..1e31591e1f 100644 --- a/superset/dashboards/dao.py +++ b/superset/daos/dashboard.py @@ -20,16 +20,28 @@ from datetime import datetime from typing import Any, Optional, Union from flask import g +from flask_appbuilder.models.sqla import Model from flask_appbuilder.models.sqla.interface import SQLAInterface from sqlalchemy.exc import SQLAlchemyError from superset import security_manager -from superset.dao.base import BaseDAO +from superset.daos.base import BaseDAO +from superset.daos.exceptions import DAOConfigError, DAOCreateFailedError from superset.dashboards.commands.exceptions import DashboardNotFoundError +from superset.dashboards.filter_sets.consts import ( + DASHBOARD_ID_FIELD, + DESCRIPTION_FIELD, + JSON_METADATA_FIELD, + NAME_FIELD, + OWNER_ID_FIELD, + OWNER_TYPE_FIELD, +) from superset.dashboards.filters import DashboardAccessFilter, is_uuid from superset.extensions import db from superset.models.core import FavStar, FavStarClassName from superset.models.dashboard import Dashboard, id_or_slug_filter +from superset.models.embedded_dashboard import EmbeddedDashboard +from superset.models.filter_set import FilterSet from superset.models.slice import Slice from superset.utils.core import get_user_id from superset.utils.dashboard_filter_scopes_converter import copy_filter_scopes @@ -365,3 +377,59 @@ class DashboardDAO(BaseDAO): if fav: db.session.delete(fav) db.session.commit() + + +class EmbeddedDashboardDAO(BaseDAO): + model_cls = EmbeddedDashboard + # There isn't really a regular scenario where we would rather get Embedded by id + id_column_name = "uuid" + + @staticmethod + def upsert(dashboard: Dashboard, allowed_domains: list[str]) -> EmbeddedDashboard: + """ + Sets up a dashboard to be embeddable. + Upsert is used to preserve the embedded_dashboard uuid across updates. + """ + embedded: EmbeddedDashboard = ( + dashboard.embedded[0] if dashboard.embedded else EmbeddedDashboard() + ) + embedded.allow_domain_list = ",".join(allowed_domains) + dashboard.embedded = [embedded] + db.session.commit() + return embedded + + @classmethod + def create(cls, properties: dict[str, Any], commit: bool = True) -> Any: + """ + Use EmbeddedDashboardDAO.upsert() instead. + At least, until we are ok with more than one embedded instance per dashboard. + """ + raise NotImplementedError("Use EmbeddedDashboardDAO.upsert() instead.") + + +class FilterSetDAO(BaseDAO): + model_cls = FilterSet + + @classmethod + def create(cls, properties: dict[str, Any], commit: bool = True) -> Model: + if cls.model_cls is None: + raise DAOConfigError() + model = FilterSet() + setattr(model, NAME_FIELD, properties[NAME_FIELD]) + setattr(model, JSON_METADATA_FIELD, properties[JSON_METADATA_FIELD]) + setattr(model, DESCRIPTION_FIELD, properties.get(DESCRIPTION_FIELD, None)) + setattr( + model, + OWNER_ID_FIELD, + properties.get(OWNER_ID_FIELD, properties[DASHBOARD_ID_FIELD]), + ) + setattr(model, OWNER_TYPE_FIELD, properties[OWNER_TYPE_FIELD]) + setattr(model, DASHBOARD_ID_FIELD, properties[DASHBOARD_ID_FIELD]) + try: + db.session.add(model) + if commit: + db.session.commit() + except SQLAlchemyError as ex: # pragma: no cover + db.session.rollback() + raise DAOCreateFailedError() from ex + return model diff --git a/superset/databases/dao.py b/superset/daos/database.py similarity index 84% rename from superset/databases/dao.py rename to superset/daos/database.py index 9ce3b5e73e..569568472a 100644 --- a/superset/databases/dao.py +++ b/superset/daos/database.py @@ -17,7 +17,7 @@ import logging from typing import Any, Optional -from superset.dao.base import BaseDAO +from superset.daos.base import BaseDAO from superset.databases.filters import DatabaseFilter from superset.databases.ssh_tunnel.models import SSHTunnel from superset.extensions import db @@ -26,6 +26,7 @@ from superset.models.dashboard import Dashboard from superset.models.slice import Slice from superset.models.sql_lab import TabState from superset.utils.core import DatasourceType +from superset.utils.ssh_tunnel import unmask_password_info logger = logging.getLogger(__name__) @@ -135,3 +136,28 @@ class DatabaseDAO(BaseDAO): ) return ssh_tunnel + + +class SSHTunnelDAO(BaseDAO): + model_cls = SSHTunnel + + @classmethod + def update( + cls, + model: SSHTunnel, + properties: dict[str, Any], + commit: bool = True, + ) -> SSHTunnel: + """ + Unmask ``password``, ``private_key`` and ``private_key_password`` before updating. + + When a database is edited the user sees a masked version of + the aforementioned fields. + + The masked values should be unmasked before the ssh tunnel is updated. + """ + # ID cannot be updated so we remove it if present in the payload + properties.pop("id", None) + properties = unmask_password_info(properties, model) + + return super().update(model, properties, commit) diff --git a/superset/datasets/dao.py b/superset/daos/dataset.py similarity index 99% rename from superset/datasets/dao.py rename to superset/daos/dataset.py index f4d46be109..3937e6c312 100644 --- a/superset/datasets/dao.py +++ b/superset/daos/dataset.py @@ -20,7 +20,7 @@ from typing import Any, Optional from sqlalchemy.exc import SQLAlchemyError from superset.connectors.sqla.models import SqlaTable, SqlMetric, TableColumn -from superset.dao.base import BaseDAO +from superset.daos.base import BaseDAO from superset.extensions import db from superset.models.core import Database from superset.models.dashboard import Dashboard diff --git a/superset/datasource/dao.py b/superset/daos/datasource.py similarity index 94% rename from superset/datasource/dao.py rename to superset/daos/datasource.py index 4682f070e2..684106161c 100644 --- a/superset/datasource/dao.py +++ b/superset/daos/datasource.py @@ -21,8 +21,8 @@ from typing import Union from sqlalchemy.orm import Session from superset.connectors.sqla.models import SqlaTable -from superset.dao.base import BaseDAO -from superset.dao.exceptions import DatasourceNotFound, DatasourceTypeNotSupportedError +from superset.daos.base import BaseDAO +from superset.daos.exceptions import DatasourceNotFound, DatasourceTypeNotSupportedError from superset.datasets.models import Dataset from superset.models.sql_lab import Query, SavedQuery from superset.tables.models import Table diff --git a/superset/dao/exceptions.py b/superset/daos/exceptions.py similarity index 100% rename from superset/dao/exceptions.py rename to superset/daos/exceptions.py diff --git a/superset/views/log/dao.py b/superset/daos/log.py similarity index 99% rename from superset/views/log/dao.py rename to superset/daos/log.py index ab2961ade6..81767a48cb 100644 --- a/superset/views/log/dao.py +++ b/superset/daos/log.py @@ -22,7 +22,7 @@ from sqlalchemy import and_, or_ from sqlalchemy.sql import functions as func from superset import db -from superset.dao.base import BaseDAO +from superset.daos.base import BaseDAO from superset.models.core import Log from superset.models.dashboard import Dashboard from superset.models.slice import Slice diff --git a/superset/queries/dao.py b/superset/daos/query.py similarity index 80% rename from superset/queries/dao.py rename to superset/daos/query.py index e9fe15cac5..8aca1a4e25 100644 --- a/superset/queries/dao.py +++ b/superset/daos/query.py @@ -16,15 +16,19 @@ # under the License. import logging from datetime import datetime -from typing import Any, Union +from typing import Any, Optional, Union + +from sqlalchemy.exc import SQLAlchemyError from superset import sql_lab from superset.common.db_query_status import QueryStatus -from superset.dao.base import BaseDAO +from superset.daos.base import BaseDAO +from superset.daos.exceptions import DAODeleteFailedError from superset.exceptions import QueryNotFoundException, SupersetCancelQueryException from superset.extensions import db from superset.models.sql_lab import Query, SavedQuery from superset.queries.filters import QueryFilter +from superset.queries.saved_queries.filters import SavedQueryFilter from superset.utils.core import get_user_id from superset.utils.dates import now_as_float @@ -95,3 +99,21 @@ class QueryDAO(BaseDAO): query.status = QueryStatus.STOPPED query.end_time = now_as_float() db.session.commit() + + +class SavedQueryDAO(BaseDAO): + model_cls = SavedQuery + base_filter = SavedQueryFilter + + @staticmethod + def bulk_delete(models: Optional[list[SavedQuery]], commit: bool = True) -> None: + item_ids = [model.id for model in models] if models else [] + try: + db.session.query(SavedQuery).filter(SavedQuery.id.in_(item_ids)).delete( + synchronize_session="fetch" + ) + if commit: + db.session.commit() + except SQLAlchemyError as ex: + db.session.rollback() + raise DAODeleteFailedError() from ex diff --git a/superset/reports/dao.py b/superset/daos/report.py similarity index 98% rename from superset/reports/dao.py rename to superset/daos/report.py index 64777e959a..4f8d914adc 100644 --- a/superset/reports/dao.py +++ b/superset/daos/report.py @@ -23,8 +23,8 @@ from flask_appbuilder import Model from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.orm import Session -from superset.dao.base import BaseDAO -from superset.dao.exceptions import DAOCreateFailedError, DAODeleteFailedError +from superset.daos.base import BaseDAO +from superset.daos.exceptions import DAOCreateFailedError, DAODeleteFailedError from superset.extensions import db from superset.reports.filters import ReportScheduleFilter from superset.reports.models import ( diff --git a/superset/row_level_security/dao.py b/superset/daos/security.py similarity index 95% rename from superset/row_level_security/dao.py rename to superset/daos/security.py index 1226e4d549..a435f224a6 100644 --- a/superset/row_level_security/dao.py +++ b/superset/daos/security.py @@ -16,7 +16,7 @@ # under the License. from superset.connectors.sqla.models import RowLevelSecurityFilter -from superset.dao.base import BaseDAO +from superset.daos.base import BaseDAO class RLSDAO(BaseDAO): diff --git a/superset/tags/dao.py b/superset/daos/tag.py similarity index 98% rename from superset/tags/dao.py rename to superset/daos/tag.py index 9ea61f5c90..ec991edb13 100644 --- a/superset/tags/dao.py +++ b/superset/daos/tag.py @@ -20,8 +20,8 @@ from typing import Any, Optional from sqlalchemy.exc import SQLAlchemyError -from superset.dao.base import BaseDAO -from superset.dao.exceptions import DAOCreateFailedError, DAODeleteFailedError +from superset.daos.base import BaseDAO +from superset.daos.exceptions import DAOCreateFailedError, DAODeleteFailedError from superset.extensions import db from superset.models.dashboard import Dashboard from superset.models.slice import Slice diff --git a/superset/dashboards/api.py b/superset/dashboards/api.py index 2c03c81fb6..3b8b70e167 100644 --- a/superset/dashboards/api.py +++ b/superset/dashboards/api.py @@ -38,6 +38,7 @@ from superset.charts.schemas import ChartEntityResponseSchema from superset.commands.importers.exceptions import NoValidFilesFoundError from superset.commands.importers.v1.utils import get_contents_from_bundle from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod +from superset.daos.dashboard import DashboardDAO, EmbeddedDashboardDAO from superset.dashboards.commands.bulk_delete import BulkDeleteDashboardCommand from superset.dashboards.commands.create import CreateDashboardCommand from superset.dashboards.commands.delete import DeleteDashboardCommand @@ -54,7 +55,6 @@ from superset.dashboards.commands.exceptions import ( from superset.dashboards.commands.export import ExportDashboardsCommand from superset.dashboards.commands.importers.dispatcher import ImportDashboardsCommand from superset.dashboards.commands.update import UpdateDashboardCommand -from superset.dashboards.dao import DashboardDAO from superset.dashboards.filters import ( DashboardAccessFilter, DashboardCertifiedFilter, @@ -80,7 +80,6 @@ from superset.dashboards.schemas import ( openapi_spec_methods_override, thumbnail_query_schema, ) -from superset.embedded.dao import EmbeddedDAO from superset.extensions import event_logger from superset.models.dashboard import Dashboard from superset.models.embedded_dashboard import EmbeddedDashboard @@ -1320,7 +1319,7 @@ class DashboardRestApi(BaseSupersetModelRestApi): """ try: body = self.embedded_config_schema.load(request.json) - embedded = EmbeddedDAO.upsert(dashboard, body["allowed_domains"]) + embedded = EmbeddedDashboardDAO.upsert(dashboard, body["allowed_domains"]) result = self.embedded_response_schema.dump(embedded) return self.response(200, result=result) except ValidationError as error: diff --git a/superset/dashboards/commands/bulk_delete.py b/superset/dashboards/commands/bulk_delete.py index 385f1fbc6d..4802c9f101 100644 --- a/superset/dashboards/commands/bulk_delete.py +++ b/superset/dashboards/commands/bulk_delete.py @@ -22,16 +22,16 @@ from flask_babel import lazy_gettext as _ from superset import security_manager from superset.commands.base import BaseCommand from superset.commands.exceptions import DeleteFailedError +from superset.daos.dashboard import DashboardDAO +from superset.daos.report import ReportScheduleDAO from superset.dashboards.commands.exceptions import ( DashboardBulkDeleteFailedError, DashboardBulkDeleteFailedReportsExistError, DashboardForbiddenError, DashboardNotFoundError, ) -from superset.dashboards.dao import DashboardDAO from superset.exceptions import SupersetSecurityException from superset.models.dashboard import Dashboard -from superset.reports.dao import ReportScheduleDAO logger = logging.getLogger(__name__) diff --git a/superset/dashboards/commands/create.py b/superset/dashboards/commands/create.py index 58acc379ba..98ecd6eb78 100644 --- a/superset/dashboards/commands/create.py +++ b/superset/dashboards/commands/create.py @@ -22,13 +22,13 @@ from marshmallow import ValidationError from superset.commands.base import BaseCommand, CreateMixin from superset.commands.utils import populate_roles -from superset.dao.exceptions import DAOCreateFailedError +from superset.daos.dashboard import DashboardDAO +from superset.daos.exceptions import DAOCreateFailedError from superset.dashboards.commands.exceptions import ( DashboardCreateFailedError, DashboardInvalidError, DashboardSlugExistsValidationError, ) -from superset.dashboards.dao import DashboardDAO logger = logging.getLogger(__name__) diff --git a/superset/dashboards/commands/delete.py b/superset/dashboards/commands/delete.py index 8ce7cb0cbf..f774b92a51 100644 --- a/superset/dashboards/commands/delete.py +++ b/superset/dashboards/commands/delete.py @@ -22,17 +22,17 @@ from flask_babel import lazy_gettext as _ from superset import security_manager from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.dashboard import DashboardDAO +from superset.daos.exceptions import DAODeleteFailedError +from superset.daos.report import ReportScheduleDAO from superset.dashboards.commands.exceptions import ( DashboardDeleteFailedError, DashboardDeleteFailedReportsExistError, DashboardForbiddenError, DashboardNotFoundError, ) -from superset.dashboards.dao import DashboardDAO from superset.exceptions import SupersetSecurityException from superset.models.dashboard import Dashboard -from superset.reports.dao import ReportScheduleDAO logger = logging.getLogger(__name__) diff --git a/superset/dashboards/commands/export.py b/superset/dashboards/commands/export.py index 2e70e29bb0..4e25e5c1fc 100644 --- a/superset/dashboards/commands/export.py +++ b/superset/dashboards/commands/export.py @@ -28,10 +28,10 @@ import yaml from superset.charts.commands.export import ExportChartsCommand from superset.dashboards.commands.exceptions import DashboardNotFoundError from superset.dashboards.commands.importers.v1.utils import find_chart_uuids -from superset.dashboards.dao import DashboardDAO +from superset.daos.dashboard import DashboardDAO from superset.commands.export.models import ExportModelsCommand from superset.datasets.commands.export import ExportDatasetsCommand -from superset.datasets.dao import DatasetDAO +from superset.daos.dataset import DatasetDAO from superset.models.dashboard import Dashboard from superset.models.slice import Slice from superset.utils.dict_import_export import EXPORT_VERSION diff --git a/superset/dashboards/commands/importers/v1/__init__.py b/superset/dashboards/commands/importers/v1/__init__.py index 597adba6d9..e86bddec9f 100644 --- a/superset/dashboards/commands/importers/v1/__init__.py +++ b/superset/dashboards/commands/importers/v1/__init__.py @@ -24,6 +24,7 @@ from sqlalchemy.sql import select from superset.charts.commands.importers.v1.utils import import_chart from superset.charts.schemas import ImportV1ChartSchema from superset.commands.importers.v1 import ImportModelsCommand +from superset.daos.dashboard import DashboardDAO from superset.dashboards.commands.exceptions import DashboardImportError from superset.dashboards.commands.importers.v1.utils import ( find_chart_uuids, @@ -31,7 +32,6 @@ from superset.dashboards.commands.importers.v1.utils import ( import_dashboard, update_id_refs, ) -from superset.dashboards.dao import DashboardDAO from superset.dashboards.schemas import ImportV1DashboardSchema from superset.databases.commands.importers.v1.utils import import_database from superset.databases.schemas import ImportV1DatabaseSchema diff --git a/superset/dashboards/commands/update.py b/superset/dashboards/commands/update.py index fefa65e3f6..cd9c07e0fd 100644 --- a/superset/dashboards/commands/update.py +++ b/superset/dashboards/commands/update.py @@ -24,7 +24,8 @@ from marshmallow import ValidationError from superset import security_manager from superset.commands.base import BaseCommand, UpdateMixin from superset.commands.utils import populate_roles -from superset.dao.exceptions import DAOUpdateFailedError +from superset.daos.dashboard import DashboardDAO +from superset.daos.exceptions import DAOUpdateFailedError from superset.dashboards.commands.exceptions import ( DashboardForbiddenError, DashboardInvalidError, @@ -32,7 +33,6 @@ from superset.dashboards.commands.exceptions import ( DashboardSlugExistsValidationError, DashboardUpdateFailedError, ) -from superset.dashboards.dao import DashboardDAO from superset.exceptions import SupersetSecurityException from superset.extensions import db from superset.models.dashboard import Dashboard diff --git a/superset/dashboards/filter_sets/api.py b/superset/dashboards/filter_sets/api.py index d236b16d9c..11291b91cc 100644 --- a/superset/dashboards/filter_sets/api.py +++ b/superset/dashboards/filter_sets/api.py @@ -30,8 +30,8 @@ from flask_appbuilder.models.sqla.interface import SQLAInterface from marshmallow import ValidationError from superset.commands.exceptions import ObjectNotFoundError +from superset.daos.dashboard import DashboardDAO from superset.dashboards.commands.exceptions import DashboardNotFoundError -from superset.dashboards.dao import DashboardDAO from superset.dashboards.filter_sets.commands.create import CreateFilterSetCommand from superset.dashboards.filter_sets.commands.delete import DeleteFilterSetCommand from superset.dashboards.filter_sets.commands.exceptions import ( diff --git a/superset/dashboards/filter_sets/commands/base.py b/superset/dashboards/filter_sets/commands/base.py index a7897eca8e..8c53e8a818 100644 --- a/superset/dashboards/filter_sets/commands/base.py +++ b/superset/dashboards/filter_sets/commands/base.py @@ -21,8 +21,8 @@ from flask_appbuilder.models.sqla import Model from superset import security_manager from superset.common.not_authorized_object import NotAuthorizedException +from superset.daos.dashboard import DashboardDAO from superset.dashboards.commands.exceptions import DashboardNotFoundError -from superset.dashboards.dao import DashboardDAO from superset.dashboards.filter_sets.commands.exceptions import ( FilterSetForbiddenError, FilterSetNotFoundError, diff --git a/superset/dashboards/filter_sets/commands/create.py b/superset/dashboards/filter_sets/commands/create.py index 63c4534786..127cd9e2c3 100644 --- a/superset/dashboards/filter_sets/commands/create.py +++ b/superset/dashboards/filter_sets/commands/create.py @@ -20,6 +20,7 @@ from typing import Any from flask_appbuilder.models.sqla import Model from superset import security_manager +from superset.daos.dashboard import FilterSetDAO from superset.dashboards.filter_sets.commands.base import BaseFilterSetCommand from superset.dashboards.filter_sets.commands.exceptions import ( DashboardIdInconsistencyError, @@ -32,7 +33,6 @@ from superset.dashboards.filter_sets.consts import ( OWNER_ID_FIELD, OWNER_TYPE_FIELD, ) -from superset.dashboards.filter_sets.dao import FilterSetDAO from superset.utils.core import get_user_id logger = logging.getLogger(__name__) diff --git a/superset/dashboards/filter_sets/commands/delete.py b/superset/dashboards/filter_sets/commands/delete.py index c416252794..93f4383399 100644 --- a/superset/dashboards/filter_sets/commands/delete.py +++ b/superset/dashboards/filter_sets/commands/delete.py @@ -18,14 +18,14 @@ import logging from flask_appbuilder.models.sqla import Model -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.dashboard import FilterSetDAO +from superset.daos.exceptions import DAODeleteFailedError from superset.dashboards.filter_sets.commands.base import BaseFilterSetCommand from superset.dashboards.filter_sets.commands.exceptions import ( FilterSetDeleteFailedError, FilterSetForbiddenError, FilterSetNotFoundError, ) -from superset.dashboards.filter_sets.dao import FilterSetDAO logger = logging.getLogger(__name__) diff --git a/superset/dashboards/filter_sets/commands/update.py b/superset/dashboards/filter_sets/commands/update.py index 722672d668..eecaa34aeb 100644 --- a/superset/dashboards/filter_sets/commands/update.py +++ b/superset/dashboards/filter_sets/commands/update.py @@ -19,13 +19,13 @@ from typing import Any from flask_appbuilder.models.sqla import Model -from superset.dao.exceptions import DAOUpdateFailedError +from superset.daos.dashboard import FilterSetDAO +from superset.daos.exceptions import DAOUpdateFailedError from superset.dashboards.filter_sets.commands.base import BaseFilterSetCommand from superset.dashboards.filter_sets.commands.exceptions import ( FilterSetUpdateFailedError, ) from superset.dashboards.filter_sets.consts import OWNER_ID_FIELD, OWNER_TYPE_FIELD -from superset.dashboards.filter_sets.dao import FilterSetDAO logger = logging.getLogger(__name__) diff --git a/superset/dashboards/filter_sets/dao.py b/superset/dashboards/filter_sets/dao.py deleted file mode 100644 index 5f2b0ba418..0000000000 --- a/superset/dashboards/filter_sets/dao.py +++ /dev/null @@ -1,64 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -import logging -from typing import Any - -from flask_appbuilder.models.sqla import Model -from sqlalchemy.exc import SQLAlchemyError - -from superset.dao.base import BaseDAO -from superset.dao.exceptions import DAOConfigError, DAOCreateFailedError -from superset.dashboards.filter_sets.consts import ( - DASHBOARD_ID_FIELD, - DESCRIPTION_FIELD, - JSON_METADATA_FIELD, - NAME_FIELD, - OWNER_ID_FIELD, - OWNER_TYPE_FIELD, -) -from superset.extensions import db -from superset.models.filter_set import FilterSet - -logger = logging.getLogger(__name__) - - -class FilterSetDAO(BaseDAO): - model_cls = FilterSet - - @classmethod - def create(cls, properties: dict[str, Any], commit: bool = True) -> Model: - if cls.model_cls is None: - raise DAOConfigError() - model = FilterSet() - setattr(model, NAME_FIELD, properties[NAME_FIELD]) - setattr(model, JSON_METADATA_FIELD, properties[JSON_METADATA_FIELD]) - setattr(model, DESCRIPTION_FIELD, properties.get(DESCRIPTION_FIELD, None)) - setattr( - model, - OWNER_ID_FIELD, - properties.get(OWNER_ID_FIELD, properties[DASHBOARD_ID_FIELD]), - ) - setattr(model, OWNER_TYPE_FIELD, properties[OWNER_TYPE_FIELD]) - setattr(model, DASHBOARD_ID_FIELD, properties[DASHBOARD_ID_FIELD]) - try: - db.session.add(model) - if commit: - db.session.commit() - except SQLAlchemyError as ex: # pragma: no cover - db.session.rollback() - raise DAOCreateFailedError() from ex - return model diff --git a/superset/dashboards/filter_state/commands/utils.py b/superset/dashboards/filter_state/commands/utils.py index 35f940f434..7e52518249 100644 --- a/superset/dashboards/filter_state/commands/utils.py +++ b/superset/dashboards/filter_state/commands/utils.py @@ -15,11 +15,11 @@ # specific language governing permissions and limitations # under the License. +from superset.daos.dashboard import DashboardDAO from superset.dashboards.commands.exceptions import ( DashboardAccessDeniedError, DashboardNotFoundError, ) -from superset.dashboards.dao import DashboardDAO from superset.temporary_cache.commands.exceptions import ( TemporaryCacheAccessDeniedError, TemporaryCacheResourceNotFoundError, diff --git a/superset/dashboards/permalink/commands/create.py b/superset/dashboards/permalink/commands/create.py index f0cf3e71cb..320003ff3d 100644 --- a/superset/dashboards/permalink/commands/create.py +++ b/superset/dashboards/permalink/commands/create.py @@ -18,7 +18,7 @@ import logging from sqlalchemy.exc import SQLAlchemyError -from superset.dashboards.dao import DashboardDAO +from superset.daos.dashboard import DashboardDAO from superset.dashboards.permalink.commands.base import BaseDashboardPermalinkCommand from superset.dashboards.permalink.exceptions import DashboardPermalinkCreateFailedError from superset.dashboards.permalink.types import DashboardPermalinkState diff --git a/superset/dashboards/permalink/commands/get.py b/superset/dashboards/permalink/commands/get.py index da54ae0b66..6b32a459a5 100644 --- a/superset/dashboards/permalink/commands/get.py +++ b/superset/dashboards/permalink/commands/get.py @@ -19,8 +19,8 @@ from typing import Optional from sqlalchemy.exc import SQLAlchemyError +from superset.daos.dashboard import DashboardDAO from superset.dashboards.commands.exceptions import DashboardNotFoundError -from superset.dashboards.dao import DashboardDAO from superset.dashboards.permalink.commands.base import BaseDashboardPermalinkCommand from superset.dashboards.permalink.exceptions import DashboardPermalinkGetFailedError from superset.dashboards.permalink.types import DashboardPermalinkValue diff --git a/superset/databases/api.py b/superset/databases/api.py index c214065a27..8f7569af92 100644 --- a/superset/databases/api.py +++ b/superset/databases/api.py @@ -35,6 +35,7 @@ from superset.commands.importers.exceptions import ( ) from superset.commands.importers.v1.utils import get_contents_from_bundle from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod +from superset.daos.database import DatabaseDAO from superset.databases.commands.create import CreateDatabaseCommand from superset.databases.commands.delete import DeleteDatabaseCommand from superset.databases.commands.exceptions import ( @@ -55,7 +56,6 @@ from superset.databases.commands.test_connection import TestConnectionDatabaseCo from superset.databases.commands.update import UpdateDatabaseCommand from superset.databases.commands.validate import ValidateDatabaseParametersCommand from superset.databases.commands.validate_sql import ValidateSQLCommand -from superset.databases.dao import DatabaseDAO from superset.databases.decorators import check_datasource_access from superset.databases.filters import DatabaseFilter, DatabaseUploadEnabledFilter from superset.databases.schemas import ( diff --git a/superset/databases/commands/create.py b/superset/databases/commands/create.py index e3fd667130..a8681c5048 100644 --- a/superset/databases/commands/create.py +++ b/superset/databases/commands/create.py @@ -23,7 +23,8 @@ from marshmallow import ValidationError from superset import is_feature_enabled from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAOCreateFailedError +from superset.daos.database import DatabaseDAO +from superset.daos.exceptions import DAOCreateFailedError from superset.databases.commands.exceptions import ( DatabaseConnectionFailedError, DatabaseCreateFailedError, @@ -32,7 +33,6 @@ from superset.databases.commands.exceptions import ( DatabaseRequiredFieldValidationError, ) from superset.databases.commands.test_connection import TestConnectionDatabaseCommand -from superset.databases.dao import DatabaseDAO from superset.databases.ssh_tunnel.commands.create import CreateSSHTunnelCommand from superset.databases.ssh_tunnel.commands.exceptions import ( SSHTunnelCreateFailedError, diff --git a/superset/databases/commands/delete.py b/superset/databases/commands/delete.py index 825b126218..b8eb3f6e5e 100644 --- a/superset/databases/commands/delete.py +++ b/superset/databases/commands/delete.py @@ -21,16 +21,16 @@ from flask_appbuilder.models.sqla import Model from flask_babel import lazy_gettext as _ from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.database import DatabaseDAO +from superset.daos.exceptions import DAODeleteFailedError +from superset.daos.report import ReportScheduleDAO from superset.databases.commands.exceptions import ( DatabaseDeleteDatasetsExistFailedError, DatabaseDeleteFailedError, DatabaseDeleteFailedReportsExistError, DatabaseNotFoundError, ) -from superset.databases.dao import DatabaseDAO from superset.models.core import Database -from superset.reports.dao import ReportScheduleDAO logger = logging.getLogger(__name__) diff --git a/superset/databases/commands/export.py b/superset/databases/commands/export.py index 889cb86c8f..71dc55a026 100644 --- a/superset/databases/commands/export.py +++ b/superset/databases/commands/export.py @@ -24,7 +24,7 @@ from collections.abc import Iterator import yaml from superset.databases.commands.exceptions import DatabaseNotFoundError -from superset.databases.dao import DatabaseDAO +from superset.daos.database import DatabaseDAO from superset.commands.export.models import ExportModelsCommand from superset.models.core import Database from superset.utils.dict_import_export import EXPORT_VERSION diff --git a/superset/databases/commands/importers/v1/__init__.py b/superset/databases/commands/importers/v1/__init__.py index ba119beaaa..585c2d54ca 100644 --- a/superset/databases/commands/importers/v1/__init__.py +++ b/superset/databases/commands/importers/v1/__init__.py @@ -21,9 +21,9 @@ from marshmallow import Schema from sqlalchemy.orm import Session from superset.commands.importers.v1 import ImportModelsCommand +from superset.daos.database import DatabaseDAO from superset.databases.commands.exceptions import DatabaseImportError from superset.databases.commands.importers.v1.utils import import_database -from superset.databases.dao import DatabaseDAO from superset.databases.schemas import ImportV1DatabaseSchema from superset.datasets.commands.importers.v1.utils import import_dataset from superset.datasets.schemas import ImportV1DatasetSchema diff --git a/superset/databases/commands/tables.py b/superset/databases/commands/tables.py index 4f262225a4..6232470ece 100644 --- a/superset/databases/commands/tables.py +++ b/superset/databases/commands/tables.py @@ -21,11 +21,11 @@ from sqlalchemy.orm import lazyload, load_only from superset.commands.base import BaseCommand from superset.connectors.sqla.models import SqlaTable +from superset.daos.database import DatabaseDAO from superset.databases.commands.exceptions import ( DatabaseNotFoundError, DatabaseTablesUnexpectedError, ) -from superset.databases.dao import DatabaseDAO from superset.exceptions import SupersetException from superset.extensions import db, security_manager from superset.models.core import Database diff --git a/superset/databases/commands/test_connection.py b/superset/databases/commands/test_connection.py index 2680c5e8c1..49c5340dd2 100644 --- a/superset/databases/commands/test_connection.py +++ b/superset/databases/commands/test_connection.py @@ -27,16 +27,15 @@ from sqlalchemy.exc import DBAPIError, NoSuchModuleError from superset import is_feature_enabled from superset.commands.base import BaseCommand +from superset.daos.database import DatabaseDAO, SSHTunnelDAO from superset.databases.commands.exceptions import ( DatabaseSecurityUnsafeError, DatabaseTestConnectionDriverError, DatabaseTestConnectionUnexpectedError, ) -from superset.databases.dao import DatabaseDAO from superset.databases.ssh_tunnel.commands.exceptions import ( SSHTunnelingNotEnabledError, ) -from superset.databases.ssh_tunnel.dao import SSHTunnelDAO from superset.databases.ssh_tunnel.models import SSHTunnel from superset.databases.utils import make_url_safe from superset.errors import ErrorLevel, SupersetErrorType diff --git a/superset/databases/commands/update.py b/superset/databases/commands/update.py index f12706fa1d..ea49801aac 100644 --- a/superset/databases/commands/update.py +++ b/superset/databases/commands/update.py @@ -22,7 +22,8 @@ from marshmallow import ValidationError from superset import is_feature_enabled from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAOCreateFailedError, DAOUpdateFailedError +from superset.daos.database import DatabaseDAO +from superset.daos.exceptions import DAOCreateFailedError, DAOUpdateFailedError from superset.databases.commands.exceptions import ( DatabaseConnectionFailedError, DatabaseExistsValidationError, @@ -30,7 +31,6 @@ from superset.databases.commands.exceptions import ( DatabaseNotFoundError, DatabaseUpdateFailedError, ) -from superset.databases.dao import DatabaseDAO from superset.databases.ssh_tunnel.commands.create import CreateSSHTunnelCommand from superset.databases.ssh_tunnel.commands.exceptions import ( SSHTunnelCreateFailedError, diff --git a/superset/databases/commands/validate.py b/superset/databases/commands/validate.py index d97ad33af9..6ea412b490 100644 --- a/superset/databases/commands/validate.py +++ b/superset/databases/commands/validate.py @@ -21,13 +21,13 @@ from typing import Any, Optional from flask_babel import gettext as __ from superset.commands.base import BaseCommand +from superset.daos.database import DatabaseDAO from superset.databases.commands.exceptions import ( DatabaseOfflineError, DatabaseTestConnectionFailedError, InvalidEngineError, InvalidParametersError, ) -from superset.databases.dao import DatabaseDAO from superset.databases.utils import make_url_safe from superset.db_engine_specs import get_engine_spec from superset.errors import ErrorLevel, SupersetError, SupersetErrorType diff --git a/superset/databases/commands/validate_sql.py b/superset/databases/commands/validate_sql.py index 40d88af745..1ac378a03c 100644 --- a/superset/databases/commands/validate_sql.py +++ b/superset/databases/commands/validate_sql.py @@ -22,6 +22,7 @@ from flask import current_app from flask_babel import gettext as __ from superset.commands.base import BaseCommand +from superset.daos.database import DatabaseDAO from superset.databases.commands.exceptions import ( DatabaseNotFoundError, NoValidatorConfigFoundError, @@ -30,7 +31,6 @@ from superset.databases.commands.exceptions import ( ValidatorSQLError, ValidatorSQLUnexpectedError, ) -from superset.databases.dao import DatabaseDAO from superset.errors import ErrorLevel, SupersetError, SupersetErrorType from superset.models.core import Database from superset.sql_validators import get_validator_by_name diff --git a/superset/databases/ssh_tunnel/commands/create.py b/superset/databases/ssh_tunnel/commands/create.py index 9c41b83392..6fb8a92f4f 100644 --- a/superset/databases/ssh_tunnel/commands/create.py +++ b/superset/databases/ssh_tunnel/commands/create.py @@ -21,13 +21,13 @@ from flask_appbuilder.models.sqla import Model from marshmallow import ValidationError from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAOCreateFailedError +from superset.daos.database import SSHTunnelDAO +from superset.daos.exceptions import DAOCreateFailedError from superset.databases.ssh_tunnel.commands.exceptions import ( SSHTunnelCreateFailedError, SSHTunnelInvalidError, SSHTunnelRequiredFieldValidationError, ) -from superset.databases.ssh_tunnel.dao import SSHTunnelDAO from superset.extensions import db, event_logger logger = logging.getLogger(__name__) diff --git a/superset/databases/ssh_tunnel/commands/delete.py b/superset/databases/ssh_tunnel/commands/delete.py index 235ceb697b..910df35a19 100644 --- a/superset/databases/ssh_tunnel/commands/delete.py +++ b/superset/databases/ssh_tunnel/commands/delete.py @@ -21,13 +21,13 @@ from flask_appbuilder.models.sqla import Model from superset import is_feature_enabled from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.database import SSHTunnelDAO +from superset.daos.exceptions import DAODeleteFailedError from superset.databases.ssh_tunnel.commands.exceptions import ( SSHTunnelDeleteFailedError, SSHTunnelingNotEnabledError, SSHTunnelNotFoundError, ) -from superset.databases.ssh_tunnel.dao import SSHTunnelDAO from superset.databases.ssh_tunnel.models import SSHTunnel logger = logging.getLogger(__name__) diff --git a/superset/databases/ssh_tunnel/commands/update.py b/superset/databases/ssh_tunnel/commands/update.py index 37fd4a94b9..4e4edcb664 100644 --- a/superset/databases/ssh_tunnel/commands/update.py +++ b/superset/databases/ssh_tunnel/commands/update.py @@ -20,14 +20,14 @@ from typing import Any, Optional from flask_appbuilder.models.sqla import Model from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAOUpdateFailedError +from superset.daos.database import SSHTunnelDAO +from superset.daos.exceptions import DAOUpdateFailedError from superset.databases.ssh_tunnel.commands.exceptions import ( SSHTunnelInvalidError, SSHTunnelNotFoundError, SSHTunnelRequiredFieldValidationError, SSHTunnelUpdateFailedError, ) -from superset.databases.ssh_tunnel.dao import SSHTunnelDAO from superset.databases.ssh_tunnel.models import SSHTunnel logger = logging.getLogger(__name__) diff --git a/superset/databases/ssh_tunnel/dao.py b/superset/databases/ssh_tunnel/dao.py deleted file mode 100644 index 731f9183b3..0000000000 --- a/superset/databases/ssh_tunnel/dao.py +++ /dev/null @@ -1,49 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -import logging -from typing import Any - -from superset.dao.base import BaseDAO -from superset.databases.ssh_tunnel.models import SSHTunnel -from superset.utils.ssh_tunnel import unmask_password_info - -logger = logging.getLogger(__name__) - - -class SSHTunnelDAO(BaseDAO): - model_cls = SSHTunnel - - @classmethod - def update( - cls, - model: SSHTunnel, - properties: dict[str, Any], - commit: bool = True, - ) -> SSHTunnel: - """ - Unmask ``password``, ``private_key`` and ``private_key_password`` before updating. - - When a database is edited the user sees a masked version of - the aforementioned fields. - - The masked values should be unmasked before the ssh tunnel is updated. - """ - # ID cannot be updated so we remove it if present in the payload - properties.pop("id", None) - properties = unmask_password_info(properties, model) - - return super().update(model, properties, commit) diff --git a/superset/datasets/api.py b/superset/datasets/api.py index c043efc682..b2457b066a 100644 --- a/superset/datasets/api.py +++ b/superset/datasets/api.py @@ -33,6 +33,7 @@ from superset.commands.importers.exceptions import NoValidFilesFoundError from superset.commands.importers.v1.utils import get_contents_from_bundle from superset.connectors.sqla.models import SqlaTable from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod +from superset.daos.dataset import DatasetDAO from superset.databases.filters import DatabaseFilter from superset.datasets.commands.bulk_delete import BulkDeleteDatasetCommand from superset.datasets.commands.create import CreateDatasetCommand @@ -52,7 +53,6 @@ from superset.datasets.commands.export import ExportDatasetsCommand from superset.datasets.commands.importers.dispatcher import ImportDatasetsCommand from superset.datasets.commands.refresh import RefreshDatasetCommand from superset.datasets.commands.update import UpdateDatasetCommand -from superset.datasets.dao import DatasetDAO from superset.datasets.filters import DatasetCertifiedFilter, DatasetIsNullOrEmptyFilter from superset.datasets.schemas import ( DatasetDuplicateSchema, diff --git a/superset/datasets/columns/commands/delete.py b/superset/datasets/columns/commands/delete.py index 8fb27f9386..6ff8c21d7d 100644 --- a/superset/datasets/columns/commands/delete.py +++ b/superset/datasets/columns/commands/delete.py @@ -22,13 +22,13 @@ from flask_appbuilder.models.sqla import Model from superset import security_manager from superset.commands.base import BaseCommand from superset.connectors.sqla.models import TableColumn -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.dataset import DatasetDAO +from superset.daos.exceptions import DAODeleteFailedError from superset.datasets.columns.commands.exceptions import ( DatasetColumnDeleteFailedError, DatasetColumnForbiddenError, DatasetColumnNotFoundError, ) -from superset.datasets.dao import DatasetDAO from superset.exceptions import SupersetSecurityException logger = logging.getLogger(__name__) diff --git a/superset/datasets/commands/bulk_delete.py b/superset/datasets/commands/bulk_delete.py index fd13351809..9733aa21e8 100644 --- a/superset/datasets/commands/bulk_delete.py +++ b/superset/datasets/commands/bulk_delete.py @@ -21,12 +21,12 @@ from superset import security_manager from superset.commands.base import BaseCommand from superset.commands.exceptions import DeleteFailedError from superset.connectors.sqla.models import SqlaTable +from superset.daos.dataset import DatasetDAO from superset.datasets.commands.exceptions import ( DatasetBulkDeleteFailedError, DatasetForbiddenError, DatasetNotFoundError, ) -from superset.datasets.dao import DatasetDAO from superset.exceptions import SupersetSecurityException from superset.extensions import db diff --git a/superset/datasets/commands/create.py b/superset/datasets/commands/create.py index 1c864ad196..28b0250ab3 100644 --- a/superset/datasets/commands/create.py +++ b/superset/datasets/commands/create.py @@ -22,7 +22,8 @@ from marshmallow import ValidationError from sqlalchemy.exc import SQLAlchemyError from superset.commands.base import BaseCommand, CreateMixin -from superset.dao.exceptions import DAOCreateFailedError +from superset.daos.dataset import DatasetDAO +from superset.daos.exceptions import DAOCreateFailedError from superset.datasets.commands.exceptions import ( DatabaseNotFoundValidationError, DatasetCreateFailedError, @@ -30,7 +31,6 @@ from superset.datasets.commands.exceptions import ( DatasetInvalidError, TableNotFoundValidationError, ) -from superset.datasets.dao import DatasetDAO from superset.extensions import db logger = logging.getLogger(__name__) diff --git a/superset/datasets/commands/delete.py b/superset/datasets/commands/delete.py index 1487f1028b..7078f09c37 100644 --- a/superset/datasets/commands/delete.py +++ b/superset/datasets/commands/delete.py @@ -23,13 +23,13 @@ from sqlalchemy.exc import SQLAlchemyError from superset import security_manager from superset.commands.base import BaseCommand from superset.connectors.sqla.models import SqlaTable -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.dataset import DatasetDAO +from superset.daos.exceptions import DAODeleteFailedError from superset.datasets.commands.exceptions import ( DatasetDeleteFailedError, DatasetForbiddenError, DatasetNotFoundError, ) -from superset.datasets.dao import DatasetDAO from superset.exceptions import SupersetSecurityException from superset.extensions import db diff --git a/superset/datasets/commands/duplicate.py b/superset/datasets/commands/duplicate.py index 5a4a84fdf9..dc3ccb85d4 100644 --- a/superset/datasets/commands/duplicate.py +++ b/superset/datasets/commands/duplicate.py @@ -25,14 +25,14 @@ from sqlalchemy.exc import SQLAlchemyError from superset.commands.base import BaseCommand, CreateMixin from superset.commands.exceptions import DatasourceTypeInvalidError from superset.connectors.sqla.models import SqlaTable, SqlMetric, TableColumn -from superset.dao.exceptions import DAOCreateFailedError +from superset.daos.dataset import DatasetDAO +from superset.daos.exceptions import DAOCreateFailedError from superset.datasets.commands.exceptions import ( DatasetDuplicateFailedError, DatasetExistsValidationError, DatasetInvalidError, DatasetNotFoundError, ) -from superset.datasets.dao import DatasetDAO from superset.errors import ErrorLevel, SupersetError, SupersetErrorType from superset.exceptions import SupersetErrorException from superset.extensions import db diff --git a/superset/datasets/commands/export.py b/superset/datasets/commands/export.py index 8c02a23f29..3922652322 100644 --- a/superset/datasets/commands/export.py +++ b/superset/datasets/commands/export.py @@ -24,9 +24,9 @@ import yaml from superset.commands.export.models import ExportModelsCommand from superset.connectors.sqla.models import SqlaTable -from superset.databases.dao import DatabaseDAO +from superset.daos.database import DatabaseDAO from superset.datasets.commands.exceptions import DatasetNotFoundError -from superset.datasets.dao import DatasetDAO +from superset.daos.dataset import DatasetDAO from superset.utils.dict_import_export import EXPORT_VERSION from superset.utils.file import get_filename from superset.utils.ssh_tunnel import mask_password_info diff --git a/superset/datasets/commands/importers/v1/__init__.py b/superset/datasets/commands/importers/v1/__init__.py index e753138ab8..f46c137b7e 100644 --- a/superset/datasets/commands/importers/v1/__init__.py +++ b/superset/datasets/commands/importers/v1/__init__.py @@ -21,11 +21,11 @@ from marshmallow import Schema from sqlalchemy.orm import Session from superset.commands.importers.v1 import ImportModelsCommand +from superset.daos.dataset import DatasetDAO from superset.databases.commands.importers.v1.utils import import_database from superset.databases.schemas import ImportV1DatabaseSchema from superset.datasets.commands.exceptions import DatasetImportError from superset.datasets.commands.importers.v1.utils import import_dataset -from superset.datasets.dao import DatasetDAO from superset.datasets.schemas import ImportV1DatasetSchema diff --git a/superset/datasets/commands/refresh.py b/superset/datasets/commands/refresh.py index 5277c27771..a25609636d 100644 --- a/superset/datasets/commands/refresh.py +++ b/superset/datasets/commands/refresh.py @@ -22,12 +22,12 @@ from flask_appbuilder.models.sqla import Model from superset import security_manager from superset.commands.base import BaseCommand from superset.connectors.sqla.models import SqlaTable +from superset.daos.dataset import DatasetDAO from superset.datasets.commands.exceptions import ( DatasetForbiddenError, DatasetNotFoundError, DatasetRefreshFailedError, ) -from superset.datasets.dao import DatasetDAO from superset.exceptions import SupersetSecurityException logger = logging.getLogger(__name__) diff --git a/superset/datasets/commands/update.py b/superset/datasets/commands/update.py index be9625709f..1636805567 100644 --- a/superset/datasets/commands/update.py +++ b/superset/datasets/commands/update.py @@ -25,7 +25,8 @@ from marshmallow import ValidationError from superset import security_manager from superset.commands.base import BaseCommand, UpdateMixin from superset.connectors.sqla.models import SqlaTable -from superset.dao.exceptions import DAOUpdateFailedError +from superset.daos.dataset import DatasetDAO +from superset.daos.exceptions import DAOUpdateFailedError from superset.datasets.commands.exceptions import ( DatabaseChangeValidationError, DatasetColumnNotFoundValidationError, @@ -41,7 +42,6 @@ from superset.datasets.commands.exceptions import ( DatasetNotFoundError, DatasetUpdateFailedError, ) -from superset.datasets.dao import DatasetDAO from superset.exceptions import SupersetSecurityException from superset.utils.urls import is_safe_url diff --git a/superset/datasets/metrics/commands/delete.py b/superset/datasets/metrics/commands/delete.py index d57e7fa359..5e7b2144c0 100644 --- a/superset/datasets/metrics/commands/delete.py +++ b/superset/datasets/metrics/commands/delete.py @@ -22,8 +22,8 @@ from flask_appbuilder.models.sqla import Model from superset import security_manager from superset.commands.base import BaseCommand from superset.connectors.sqla.models import SqlMetric -from superset.dao.exceptions import DAODeleteFailedError -from superset.datasets.dao import DatasetDAO +from superset.daos.dataset import DatasetDAO +from superset.daos.exceptions import DAODeleteFailedError from superset.datasets.metrics.commands.exceptions import ( DatasetMetricDeleteFailedError, DatasetMetricForbiddenError, diff --git a/superset/datasource/api.py b/superset/datasource/api.py index 471077ff70..6399d197e0 100644 --- a/superset/datasource/api.py +++ b/superset/datasource/api.py @@ -19,8 +19,8 @@ import logging from flask_appbuilder.api import expose, protect, safe from superset import app, db, event_logger -from superset.dao.exceptions import DatasourceNotFound, DatasourceTypeNotSupportedError -from superset.datasource.dao import DatasourceDAO +from superset.daos.datasource import DatasourceDAO +from superset.daos.exceptions import DatasourceNotFound, DatasourceTypeNotSupportedError from superset.exceptions import SupersetSecurityException from superset.superset_typing import FlaskResponse from superset.utils.core import apply_max_row_limit, DatasourceType diff --git a/superset/embedded/api.py b/superset/embedded/api.py index def5bf9128..229ecc81c9 100644 --- a/superset/embedded/api.py +++ b/superset/embedded/api.py @@ -24,8 +24,8 @@ from flask_appbuilder.models.sqla.interface import SQLAInterface from superset import is_feature_enabled from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod +from superset.daos.dashboard import EmbeddedDashboardDAO from superset.dashboards.schemas import EmbeddedDashboardResponseSchema -from superset.embedded.dao import EmbeddedDAO from superset.embedded_dashboard.commands.exceptions import ( EmbeddedDashboardNotFoundError, ) @@ -98,7 +98,7 @@ class EmbeddedDashboardRestApi(BaseSupersetModelRestApi): $ref: '#/components/responses/500' """ try: - embedded = EmbeddedDAO.find_by_id(uuid) + embedded = EmbeddedDashboardDAO.find_by_id(uuid) if not embedded: raise EmbeddedDashboardNotFoundError() result = self.embedded_response_schema.dump(embedded) diff --git a/superset/embedded/dao.py b/superset/embedded/dao.py deleted file mode 100644 index 27ca338502..0000000000 --- a/superset/embedded/dao.py +++ /dev/null @@ -1,53 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -import logging -from typing import Any - -from superset.dao.base import BaseDAO -from superset.extensions import db -from superset.models.dashboard import Dashboard -from superset.models.embedded_dashboard import EmbeddedDashboard - -logger = logging.getLogger(__name__) - - -class EmbeddedDAO(BaseDAO): - model_cls = EmbeddedDashboard - # There isn't really a regular scenario where we would rather get Embedded by id - id_column_name = "uuid" - - @staticmethod - def upsert(dashboard: Dashboard, allowed_domains: list[str]) -> EmbeddedDashboard: - """ - Sets up a dashboard to be embeddable. - Upsert is used to preserve the embedded_dashboard uuid across updates. - """ - embedded: EmbeddedDashboard = ( - dashboard.embedded[0] if dashboard.embedded else EmbeddedDashboard() - ) - embedded.allow_domain_list = ",".join(allowed_domains) - dashboard.embedded = [embedded] - db.session.commit() - return embedded - - @classmethod - def create(cls, properties: dict[str, Any], commit: bool = True) -> Any: - """ - Use EmbeddedDAO.upsert() instead. - At least, until we are ok with more than one embedded instance per dashboard. - """ - raise NotImplementedError("Use EmbeddedDAO.upsert() instead.") diff --git a/superset/embedded/view.py b/superset/embedded/view.py index b7062c0b5e..e59a6ced90 100644 --- a/superset/embedded/view.py +++ b/superset/embedded/view.py @@ -23,7 +23,7 @@ from flask_login import AnonymousUserMixin, login_user from flask_wtf.csrf import same_origin from superset import event_logger, is_feature_enabled -from superset.embedded.dao import EmbeddedDAO +from superset.daos.dashboard import EmbeddedDashboardDAO from superset.superset_typing import FlaskResponse from superset.utils import core as utils from superset.views.base import BaseSupersetView, common_bootstrap_payload @@ -50,7 +50,7 @@ class EmbeddedView(BaseSupersetView): if not is_feature_enabled("EMBEDDED_SUPERSET"): abort(404) - embedded = EmbeddedDAO.find_by_id(uuid) + embedded = EmbeddedDashboardDAO.find_by_id(uuid) if not embedded: abort(404) diff --git a/superset/explore/commands/get.py b/superset/explore/commands/get.py index 4543136020..148ad2a3f5 100644 --- a/superset/explore/commands/get.py +++ b/superset/explore/commands/get.py @@ -27,8 +27,8 @@ from superset import db from superset.commands.base import BaseCommand from superset.connectors.base.models import BaseDatasource from superset.connectors.sqla.models import SqlaTable -from superset.dao.exceptions import DatasourceNotFound -from superset.datasource.dao import DatasourceDAO +from superset.daos.datasource import DatasourceDAO +from superset.daos.exceptions import DatasourceNotFound from superset.exceptions import SupersetException from superset.explore.commands.parameters import CommandParameters from superset.explore.exceptions import WrongEndpointError diff --git a/superset/explore/utils.py b/superset/explore/utils.py index 01f63f53f2..ca73cb39fb 100644 --- a/superset/explore/utils.py +++ b/superset/explore/utils.py @@ -21,18 +21,18 @@ from superset.charts.commands.exceptions import ( ChartAccessDeniedError, ChartNotFoundError, ) -from superset.charts.dao import ChartDAO from superset.commands.exceptions import ( DatasourceNotFoundValidationError, DatasourceTypeInvalidError, QueryNotFoundValidationError, ) +from superset.daos.chart import ChartDAO +from superset.daos.dataset import DatasetDAO +from superset.daos.query import QueryDAO from superset.datasets.commands.exceptions import ( DatasetAccessDeniedError, DatasetNotFoundError, ) -from superset.datasets.dao import DatasetDAO -from superset.queries.dao import QueryDAO from superset.utils.core import DatasourceType diff --git a/superset/jinja_context.py b/superset/jinja_context.py index f096b65cd1..4bb0b91a4e 100644 --- a/superset/jinja_context.py +++ b/superset/jinja_context.py @@ -630,7 +630,7 @@ def dataset_macro( the user can also request metrics to be included, and columns to group by. """ # pylint: disable=import-outside-toplevel - from superset.datasets.dao import DatasetDAO + from superset.daos.dataset import DatasetDAO dataset = DatasetDAO.find_by_id(dataset_id) if not dataset: diff --git a/superset/models/core.py b/superset/models/core.py index 3a52367242..92e6f2dbb5 100755 --- a/superset/models/core.py +++ b/superset/models/core.py @@ -387,7 +387,7 @@ class Database( source: Optional[utils.QuerySource] = None, override_ssh_tunnel: Optional["SSHTunnel"] = None, ) -> Engine: - from superset.databases.dao import ( # pylint: disable=import-outside-toplevel + from superset.daos.database import ( # pylint: disable=import-outside-toplevel DatabaseDAO, ) diff --git a/superset/models/dashboard.py b/superset/models/dashboard.py index a23e25a1ab..649c5a499d 100644 --- a/superset/models/dashboard.py +++ b/superset/models/dashboard.py @@ -49,7 +49,7 @@ from sqlalchemy.sql.elements import BinaryExpression from superset import app, db, is_feature_enabled, security_manager from superset.connectors.base.models import BaseDatasource from superset.connectors.sqla.models import SqlaTable, SqlMetric, TableColumn -from superset.datasource.dao import DatasourceDAO +from superset.daos.datasource import DatasourceDAO from superset.extensions import cache_manager from superset.models.filter_set import FilterSet from superset.models.helpers import AuditMixinNullable, ImportExportMixin diff --git a/superset/models/slice.py b/superset/models/slice.py index fc8174878a..a6ffb22a08 100644 --- a/superset/models/slice.py +++ b/superset/models/slice.py @@ -137,7 +137,7 @@ class Slice( # pylint: disable=too-many-public-methods @property def cls_model(self) -> type[BaseDatasource]: # pylint: disable=import-outside-toplevel - from superset.datasource.dao import DatasourceDAO + from superset.daos.datasource import DatasourceDAO return DatasourceDAO.sources[self.datasource_type] diff --git a/superset/queries/api.py b/superset/queries/api.py index bc60742024..2b0173ec16 100644 --- a/superset/queries/api.py +++ b/superset/queries/api.py @@ -23,10 +23,10 @@ from flask_appbuilder.models.sqla.interface import SQLAInterface from superset import db, event_logger from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod +from superset.daos.query import QueryDAO from superset.databases.filters import DatabaseFilter from superset.exceptions import SupersetException from superset.models.sql_lab import Query -from superset.queries.dao import QueryDAO from superset.queries.filters import QueryFilter from superset.queries.schemas import ( openapi_spec_methods_override, diff --git a/superset/queries/saved_queries/commands/bulk_delete.py b/superset/queries/saved_queries/commands/bulk_delete.py index fb230180c8..ba01bd456a 100644 --- a/superset/queries/saved_queries/commands/bulk_delete.py +++ b/superset/queries/saved_queries/commands/bulk_delete.py @@ -18,13 +18,13 @@ import logging from typing import Optional from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.exceptions import DAODeleteFailedError +from superset.daos.query import SavedQueryDAO from superset.models.dashboard import Dashboard from superset.queries.saved_queries.commands.exceptions import ( SavedQueryBulkDeleteFailedError, SavedQueryNotFoundError, ) -from superset.queries.saved_queries.dao import SavedQueryDAO logger = logging.getLogger(__name__) diff --git a/superset/queries/saved_queries/commands/export.py b/superset/queries/saved_queries/commands/export.py index 323256306a..1b85cda796 100644 --- a/superset/queries/saved_queries/commands/export.py +++ b/superset/queries/saved_queries/commands/export.py @@ -26,7 +26,7 @@ from werkzeug.utils import secure_filename from superset.commands.export.models import ExportModelsCommand from superset.models.sql_lab import SavedQuery from superset.queries.saved_queries.commands.exceptions import SavedQueryNotFoundError -from superset.queries.saved_queries.dao import SavedQueryDAO +from superset.daos.query import SavedQueryDAO from superset.utils.dict_import_export import EXPORT_VERSION logger = logging.getLogger(__name__) diff --git a/superset/queries/saved_queries/commands/importers/v1/__init__.py b/superset/queries/saved_queries/commands/importers/v1/__init__.py index 79ec04f54b..c8a159c7f5 100644 --- a/superset/queries/saved_queries/commands/importers/v1/__init__.py +++ b/superset/queries/saved_queries/commands/importers/v1/__init__.py @@ -22,13 +22,13 @@ from sqlalchemy.orm import Session from superset.commands.importers.v1 import ImportModelsCommand from superset.connectors.sqla.models import SqlaTable +from superset.daos.query import SavedQueryDAO from superset.databases.commands.importers.v1.utils import import_database from superset.databases.schemas import ImportV1DatabaseSchema from superset.queries.saved_queries.commands.exceptions import SavedQueryImportError from superset.queries.saved_queries.commands.importers.v1.utils import ( import_saved_query, ) -from superset.queries.saved_queries.dao import SavedQueryDAO from superset.queries.saved_queries.schemas import ImportV1SavedQuerySchema diff --git a/superset/queries/saved_queries/dao.py b/superset/queries/saved_queries/dao.py deleted file mode 100644 index daae1de8f5..0000000000 --- a/superset/queries/saved_queries/dao.py +++ /dev/null @@ -1,46 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -import logging -from typing import Optional - -from sqlalchemy.exc import SQLAlchemyError - -from superset.dao.base import BaseDAO -from superset.dao.exceptions import DAODeleteFailedError -from superset.extensions import db -from superset.models.sql_lab import SavedQuery -from superset.queries.saved_queries.filters import SavedQueryFilter - -logger = logging.getLogger(__name__) - - -class SavedQueryDAO(BaseDAO): - model_cls = SavedQuery - base_filter = SavedQueryFilter - - @staticmethod - def bulk_delete(models: Optional[list[SavedQuery]], commit: bool = True) -> None: - item_ids = [model.id for model in models] if models else [] - try: - db.session.query(SavedQuery).filter(SavedQuery.id.in_(item_ids)).delete( - synchronize_session="fetch" - ) - if commit: - db.session.commit() - except SQLAlchemyError as ex: - db.session.rollback() - raise DAODeleteFailedError() from ex diff --git a/superset/reports/commands/base.py b/superset/reports/commands/base.py index 598370576b..da871ef17c 100644 --- a/superset/reports/commands/base.py +++ b/superset/reports/commands/base.py @@ -19,9 +19,9 @@ from typing import Any from marshmallow import ValidationError -from superset.charts.dao import ChartDAO from superset.commands.base import BaseCommand -from superset.dashboards.dao import DashboardDAO +from superset.daos.chart import ChartDAO +from superset.daos.dashboard import DashboardDAO from superset.reports.commands.exceptions import ( ChartNotFoundValidationError, ChartNotSavedValidationError, diff --git a/superset/reports/commands/bulk_delete.py b/superset/reports/commands/bulk_delete.py index 7d6e1ed791..a3644d9fb4 100644 --- a/superset/reports/commands/bulk_delete.py +++ b/superset/reports/commands/bulk_delete.py @@ -19,14 +19,14 @@ from typing import Optional from superset import security_manager from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.exceptions import DAODeleteFailedError +from superset.daos.report import ReportScheduleDAO from superset.exceptions import SupersetSecurityException from superset.reports.commands.exceptions import ( ReportScheduleBulkDeleteFailedError, ReportScheduleForbiddenError, ReportScheduleNotFoundError, ) -from superset.reports.dao import ReportScheduleDAO from superset.reports.models import ReportSchedule logger = logging.getLogger(__name__) diff --git a/superset/reports/commands/create.py b/superset/reports/commands/create.py index 04cf6ef43f..d8bdb03a57 100644 --- a/superset/reports/commands/create.py +++ b/superset/reports/commands/create.py @@ -22,8 +22,9 @@ from flask_babel import gettext as _ from marshmallow import ValidationError from superset.commands.base import CreateMixin -from superset.dao.exceptions import DAOCreateFailedError -from superset.databases.dao import DatabaseDAO +from superset.daos.database import DatabaseDAO +from superset.daos.exceptions import DAOCreateFailedError +from superset.daos.report import ReportScheduleDAO from superset.reports.commands.base import BaseReportScheduleCommand from superset.reports.commands.exceptions import ( DatabaseNotFoundValidationError, @@ -34,7 +35,6 @@ from superset.reports.commands.exceptions import ( ReportScheduleNameUniquenessValidationError, ReportScheduleRequiredTypeValidationError, ) -from superset.reports.dao import ReportScheduleDAO from superset.reports.models import ( ReportCreationMethod, ReportSchedule, diff --git a/superset/reports/commands/delete.py b/superset/reports/commands/delete.py index 4adf17683a..3f7e4e5d23 100644 --- a/superset/reports/commands/delete.py +++ b/superset/reports/commands/delete.py @@ -21,14 +21,14 @@ from flask_appbuilder.models.sqla import Model from superset import security_manager from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.exceptions import DAODeleteFailedError +from superset.daos.report import ReportScheduleDAO from superset.exceptions import SupersetSecurityException from superset.reports.commands.exceptions import ( ReportScheduleDeleteFailedError, ReportScheduleForbiddenError, ReportScheduleNotFoundError, ) -from superset.reports.dao import ReportScheduleDAO from superset.reports.models import ReportSchedule logger = logging.getLogger(__name__) diff --git a/superset/reports/commands/execute.py b/superset/reports/commands/execute.py index 608b2564a2..bb7c53ed5e 100644 --- a/superset/reports/commands/execute.py +++ b/superset/reports/commands/execute.py @@ -28,6 +28,10 @@ from superset import app, security_manager from superset.commands.base import BaseCommand from superset.commands.exceptions import CommandException from superset.common.chart_data import ChartDataResultFormat, ChartDataResultType +from superset.daos.report import ( + REPORT_SCHEDULE_ERROR_NOTIFICATION_MARKER, + ReportScheduleDAO, +) from superset.dashboards.permalink.commands.create import ( CreateDashboardPermalinkCommand, ) @@ -52,10 +56,6 @@ from superset.reports.commands.exceptions import ( ReportScheduleUnexpectedError, ReportScheduleWorkingTimeoutError, ) -from superset.reports.dao import ( - REPORT_SCHEDULE_ERROR_NOTIFICATION_MARKER, - ReportScheduleDAO, -) from superset.reports.models import ( ReportDataFormat, ReportExecutionLog, diff --git a/superset/reports/commands/log_prune.py b/superset/reports/commands/log_prune.py index badd267ecf..09d9995414 100644 --- a/superset/reports/commands/log_prune.py +++ b/superset/reports/commands/log_prune.py @@ -18,9 +18,9 @@ import logging from datetime import datetime, timedelta from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.exceptions import DAODeleteFailedError +from superset.daos.report import ReportScheduleDAO from superset.reports.commands.exceptions import ReportSchedulePruneLogError -from superset.reports.dao import ReportScheduleDAO from superset.reports.models import ReportSchedule from superset.utils.celery import session_scope diff --git a/superset/reports/commands/update.py b/superset/reports/commands/update.py index 5ca3ac849a..4985165f66 100644 --- a/superset/reports/commands/update.py +++ b/superset/reports/commands/update.py @@ -23,8 +23,9 @@ from marshmallow import ValidationError from superset import security_manager from superset.commands.base import UpdateMixin -from superset.dao.exceptions import DAOUpdateFailedError -from superset.databases.dao import DatabaseDAO +from superset.daos.database import DatabaseDAO +from superset.daos.exceptions import DAOUpdateFailedError +from superset.daos.report import ReportScheduleDAO from superset.exceptions import SupersetSecurityException from superset.reports.commands.base import BaseReportScheduleCommand from superset.reports.commands.exceptions import ( @@ -35,7 +36,6 @@ from superset.reports.commands.exceptions import ( ReportScheduleNotFoundError, ReportScheduleUpdateFailedError, ) -from superset.reports.dao import ReportScheduleDAO from superset.reports.models import ReportSchedule, ReportScheduleType, ReportState logger = logging.getLogger(__name__) diff --git a/superset/row_level_security/api.py b/superset/row_level_security/api.py index 05a6dddf04..43912689fb 100644 --- a/superset/row_level_security/api.py +++ b/superset/row_level_security/api.py @@ -30,7 +30,7 @@ from superset.commands.exceptions import ( ) from superset.connectors.sqla.models import RowLevelSecurityFilter from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod -from superset.dao.exceptions import DAOCreateFailedError, DAOUpdateFailedError +from superset.daos.exceptions import DAOCreateFailedError, DAOUpdateFailedError from superset.extensions import event_logger from superset.row_level_security.commands.bulk_delete import BulkDeleteRLSRuleCommand from superset.row_level_security.commands.create import CreateRLSRuleCommand diff --git a/superset/row_level_security/commands/bulk_delete.py b/superset/row_level_security/commands/bulk_delete.py index a3703346cc..f180d0b2b8 100644 --- a/superset/row_level_security/commands/bulk_delete.py +++ b/superset/row_level_security/commands/bulk_delete.py @@ -18,13 +18,13 @@ import logging from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.exceptions import DAODeleteFailedError +from superset.daos.security import RLSDAO from superset.reports.models import ReportSchedule from superset.row_level_security.commands.exceptions import ( RLSRuleNotFoundError, RuleBulkDeleteFailedError, ) -from superset.row_level_security.dao import RLSDAO logger = logging.getLogger(__name__) diff --git a/superset/row_level_security/commands/create.py b/superset/row_level_security/commands/create.py index 5552feeda0..a26fdb7b12 100644 --- a/superset/row_level_security/commands/create.py +++ b/superset/row_level_security/commands/create.py @@ -23,9 +23,9 @@ from superset.commands.base import BaseCommand from superset.commands.exceptions import DatasourceNotFoundValidationError from superset.commands.utils import populate_roles from superset.connectors.sqla.models import SqlaTable -from superset.dao.exceptions import DAOCreateFailedError +from superset.daos.exceptions import DAOCreateFailedError +from superset.daos.security import RLSDAO from superset.extensions import db -from superset.row_level_security.dao import RLSDAO logger = logging.getLogger(__name__) diff --git a/superset/row_level_security/commands/update.py b/superset/row_level_security/commands/update.py index a206fc3a39..d44aa3efaf 100644 --- a/superset/row_level_security/commands/update.py +++ b/superset/row_level_security/commands/update.py @@ -23,10 +23,10 @@ from superset.commands.base import BaseCommand from superset.commands.exceptions import DatasourceNotFoundValidationError from superset.commands.utils import populate_roles from superset.connectors.sqla.models import RowLevelSecurityFilter, SqlaTable -from superset.dao.exceptions import DAOUpdateFailedError +from superset.daos.exceptions import DAOUpdateFailedError +from superset.daos.security import RLSDAO from superset.extensions import db from superset.row_level_security.commands.exceptions import RLSRuleNotFoundError -from superset.row_level_security.dao import RLSDAO logger = logging.getLogger(__name__) diff --git a/superset/security/manager.py b/superset/security/manager.py index 99c15726f5..942ed66776 100644 --- a/superset/security/manager.py +++ b/superset/security/manager.py @@ -2071,7 +2071,7 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods @staticmethod def validate_guest_token_resources(resources: GuestTokenResources) -> None: # pylint: disable=import-outside-toplevel - from superset.embedded.dao import EmbeddedDAO + from superset.daos.dashboard import EmbeddedDashboardDAO from superset.embedded_dashboard.commands.exceptions import ( EmbeddedDashboardNotFoundError, ) @@ -2082,7 +2082,7 @@ class SupersetSecurityManager( # pylint: disable=too-many-public-methods # TODO (embedded): remove this check once uuids are rolled out dashboard = Dashboard.get(str(resource["id"])) if not dashboard: - embedded = EmbeddedDAO.find_by_id(str(resource["id"])) + embedded = EmbeddedDashboardDAO.find_by_id(str(resource["id"])) if not embedded: raise EmbeddedDashboardNotFoundError() diff --git a/superset/sqllab/api.py b/superset/sqllab/api.py index 35d110d8fc..72d1558c04 100644 --- a/superset/sqllab/api.py +++ b/superset/sqllab/api.py @@ -25,11 +25,11 @@ from flask_appbuilder.models.sqla.interface import SQLAInterface from marshmallow import ValidationError from superset import app, is_feature_enabled -from superset.databases.dao import DatabaseDAO +from superset.daos.database import DatabaseDAO +from superset.daos.query import QueryDAO from superset.extensions import event_logger from superset.jinja_context import get_template_processor from superset.models.sql_lab import Query -from superset.queries.dao import QueryDAO from superset.sql_lab import get_sql_results from superset.sqllab.command_status import SqlJsonExecutionStatus from superset.sqllab.commands.estimate import QueryEstimationCommand diff --git a/superset/sqllab/commands/execute.py b/superset/sqllab/commands/execute.py index 09b0769ce2..8b854d4971 100644 --- a/superset/sqllab/commands/execute.py +++ b/superset/sqllab/commands/execute.py @@ -25,7 +25,7 @@ from flask_babel import gettext as __ from superset.commands.base import BaseCommand from superset.common.db_query_status import QueryStatus -from superset.dao.exceptions import DAOCreateFailedError +from superset.daos.exceptions import DAOCreateFailedError from superset.errors import SupersetErrorType from superset.exceptions import ( SupersetErrorException, @@ -43,8 +43,8 @@ from superset.sqllab.execution_context_convertor import ExecutionContextConverto from superset.sqllab.limiting_factor import LimitingFactor if TYPE_CHECKING: - from superset.databases.dao import DatabaseDAO - from superset.queries.dao import QueryDAO + from superset.daos.database import DatabaseDAO + from superset.daos.query import QueryDAO from superset.sqllab.sql_json_executer import SqlJsonExecutor from superset.sqllab.sqllab_execution_context import SqlJsonExecutionContext diff --git a/superset/sqllab/sql_json_executer.py b/superset/sqllab/sql_json_executer.py index 124f477e96..a25b39ad0b 100644 --- a/superset/sqllab/sql_json_executer.py +++ b/superset/sqllab/sql_json_executer.py @@ -37,7 +37,7 @@ from superset.utils.core import get_username from superset.utils.dates import now_as_float if TYPE_CHECKING: - from superset.queries.dao import QueryDAO + from superset.daos.query import QueryDAO from superset.sqllab.sqllab_execution_context import SqlJsonExecutionContext QueryStatus = utils.QueryStatus diff --git a/superset/tags/api.py b/superset/tags/api.py index 859acdb537..f9aa7f7be9 100644 --- a/superset/tags/api.py +++ b/superset/tags/api.py @@ -22,6 +22,7 @@ from flask_appbuilder.api import expose, protect, rison, safe from flask_appbuilder.models.sqla.interface import SQLAInterface from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod +from superset.daos.tag import TagDAO from superset.extensions import event_logger from superset.tags.commands.create import CreateCustomTagCommand from superset.tags.commands.delete import DeleteTaggedObjectCommand, DeleteTagsCommand @@ -33,7 +34,6 @@ from superset.tags.commands.exceptions import ( TagInvalidError, TagNotFoundError, ) -from superset.tags.dao import TagDAO from superset.tags.models import ObjectTypes, Tag from superset.tags.schemas import ( delete_tags_schema, diff --git a/superset/tags/commands/create.py b/superset/tags/commands/create.py index 20327b54f0..7e9f040015 100644 --- a/superset/tags/commands/create.py +++ b/superset/tags/commands/create.py @@ -17,10 +17,10 @@ import logging from superset.commands.base import BaseCommand, CreateMixin -from superset.dao.exceptions import DAOCreateFailedError +from superset.daos.exceptions import DAOCreateFailedError +from superset.daos.tag import TagDAO from superset.tags.commands.exceptions import TagCreateFailedError, TagInvalidError from superset.tags.commands.utils import to_object_type -from superset.tags.dao import TagDAO from superset.tags.models import ObjectTypes logger = logging.getLogger(__name__) diff --git a/superset/tags/commands/delete.py b/superset/tags/commands/delete.py index 08189b5ac5..4b92e40ff5 100644 --- a/superset/tags/commands/delete.py +++ b/superset/tags/commands/delete.py @@ -17,7 +17,8 @@ import logging from superset.commands.base import BaseCommand -from superset.dao.exceptions import DAODeleteFailedError +from superset.daos.exceptions import DAODeleteFailedError +from superset.daos.tag import TagDAO from superset.tags.commands.exceptions import ( TagDeleteFailedError, TaggedObjectDeleteFailedError, @@ -26,7 +27,6 @@ from superset.tags.commands.exceptions import ( TagNotFoundError, ) from superset.tags.commands.utils import to_object_type -from superset.tags.dao import TagDAO from superset.tags.models import ObjectTypes from superset.views.base import DeleteMixin diff --git a/superset/tasks/scheduler.py b/superset/tasks/scheduler.py index b3efa240fa..7e0422b001 100644 --- a/superset/tasks/scheduler.py +++ b/superset/tasks/scheduler.py @@ -22,11 +22,11 @@ from dateutil import parser from superset import app, is_feature_enabled from superset.commands.exceptions import CommandException +from superset.daos.report import ReportScheduleDAO from superset.extensions import celery_app from superset.reports.commands.exceptions import ReportScheduleUnexpectedError from superset.reports.commands.execute import AsyncExecuteReportScheduleCommand from superset.reports.commands.log_prune import AsyncPruneReportScheduleLogCommand -from superset.reports.dao import ReportScheduleDAO from superset.tasks.cron_util import cron_schedule_window from superset.utils.celery import session_scope from superset.utils.core import LoggerLevel diff --git a/superset/views/core.py b/superset/views/core.py index f75a8f77e1..f584901316 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -43,17 +43,17 @@ from superset import ( security_manager, ) from superset.charts.commands.exceptions import ChartNotFoundError -from superset.charts.dao import ChartDAO from superset.common.chart_data import ChartDataResultFormat, ChartDataResultType from superset.connectors.base.models import BaseDatasource from superset.connectors.sqla.models import SqlaTable +from superset.daos.chart import ChartDAO +from superset.daos.database import DatabaseDAO +from superset.daos.datasource import DatasourceDAO from superset.dashboards.commands.exceptions import DashboardAccessDeniedError from superset.dashboards.commands.importers.v0 import ImportDashboardsCommand from superset.dashboards.permalink.commands.get import GetDashboardPermalinkCommand from superset.dashboards.permalink.exceptions import DashboardPermalinkGetFailedError -from superset.databases.dao import DatabaseDAO from superset.datasets.commands.exceptions import DatasetNotFoundError -from superset.datasource.dao import DatasourceDAO from superset.exceptions import CacheLoadError, DatabaseNotFound, SupersetException from superset.explore.form_data.commands.create import CreateFormDataCommand from superset.explore.form_data.commands.get import GetFormDataCommand diff --git a/superset/views/datasource/utils.py b/superset/views/datasource/utils.py index a4cf0c5e90..65b19c3493 100644 --- a/superset/views/datasource/utils.py +++ b/superset/views/datasource/utils.py @@ -21,8 +21,8 @@ from superset.common.chart_data import ChartDataResultType from superset.common.query_context_factory import QueryContextFactory from superset.common.utils.query_cache_manager import QueryCacheManager from superset.constants import CacheRegion +from superset.daos.datasource import DatasourceDAO from superset.datasets.commands.exceptions import DatasetSamplesFailedError -from superset.datasource.dao import DatasourceDAO from superset.utils.core import QueryStatus from superset.views.datasource.schemas import SamplesPayloadSchema diff --git a/superset/views/datasource/views.py b/superset/views/datasource/views.py index ba5a05b9cf..f1086acd47 100644 --- a/superset/views/datasource/views.py +++ b/superset/views/datasource/views.py @@ -31,11 +31,11 @@ from superset import db, event_logger, security_manager from superset.commands.utils import populate_owners from superset.connectors.sqla.models import SqlaTable from superset.connectors.sqla.utils import get_physical_table_metadata +from superset.daos.datasource import DatasourceDAO from superset.datasets.commands.exceptions import ( DatasetForbiddenError, DatasetNotFoundError, ) -from superset.datasource.dao import DatasourceDAO from superset.exceptions import SupersetException, SupersetSecurityException from superset.models.core import Database from superset.superset_typing import FlaskResponse diff --git a/superset/views/log/api.py b/superset/views/log/api.py index eefa45b5fd..d3699e3885 100644 --- a/superset/views/log/api.py +++ b/superset/views/log/api.py @@ -24,11 +24,11 @@ from flask_appbuilder.models.sqla.interface import SQLAInterface import superset.models.core as models from superset import event_logger, security_manager from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP +from superset.daos.log import LogDAO from superset.exceptions import SupersetSecurityException from superset.superset_typing import FlaskResponse from superset.views.base_api import BaseSupersetModelRestApi, statsd_metrics from superset.views.log import LogMixin -from superset.views.log.dao import LogDAO from superset.views.log.schemas import ( get_recent_activity_schema, RecentActivityResponseSchema, diff --git a/superset/views/utils.py b/superset/views/utils.py index 1f3b3930eb..29f5a4c7e4 100644 --- a/superset/views/utils.py +++ b/superset/views/utils.py @@ -33,7 +33,7 @@ from werkzeug.wrappers.response import Response import superset.models.core as models from superset import app, dataframe, db, result_set, viz from superset.common.db_query_status import QueryStatus -from superset.datasource.dao import DatasourceDAO +from superset.daos.datasource import DatasourceDAO from superset.errors import ErrorLevel, SupersetError, SupersetErrorType from superset.exceptions import ( CacheLoadError, diff --git a/tests/integration_tests/dashboards/dao_tests.py b/tests/integration_tests/dashboards/dao_tests.py index e62b28a3d7..91e27af3b6 100644 --- a/tests/integration_tests/dashboards/dao_tests.py +++ b/tests/integration_tests/dashboards/dao_tests.py @@ -23,7 +23,7 @@ import pytest import tests.integration_tests.test_app # pylint: disable=unused-import from superset import db, security_manager -from superset.dashboards.dao import DashboardDAO +from superset.daos.dashboard import DashboardDAO from superset.models.dashboard import Dashboard from tests.integration_tests.base_tests import SupersetTestCase from tests.integration_tests.fixtures.world_bank_dashboard import ( @@ -129,7 +129,7 @@ class TestDashboardDAO(SupersetTestCase): db.session.commit() @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices") - @patch("superset.dashboards.dao.g") + @patch("superset.daos.dashboard.g") def test_copy_dashboard(self, mock_g): mock_g.user = security_manager.find_user("admin") original_dash = ( @@ -155,7 +155,7 @@ class TestDashboardDAO(SupersetTestCase): db.session.commit() @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices") - @patch("superset.dashboards.dao.g") + @patch("superset.daos.dashboard.g") def test_copy_dashboard_copies_native_filters(self, mock_g): mock_g.user = security_manager.find_user("admin") original_dash = ( @@ -183,7 +183,7 @@ class TestDashboardDAO(SupersetTestCase): db.session.commit() @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices") - @patch("superset.dashboards.dao.g") + @patch("superset.daos.dashboard.g") def test_copy_dashboard_duplicate_slices(self, mock_g): mock_g.user = security_manager.find_user("admin") original_dash = ( diff --git a/tests/integration_tests/dashboards/security/security_dataset_tests.py b/tests/integration_tests/dashboards/security/security_dataset_tests.py index 875eb9145e..dffab61a7a 100644 --- a/tests/integration_tests/dashboards/security/security_dataset_tests.py +++ b/tests/integration_tests/dashboards/security/security_dataset_tests.py @@ -22,7 +22,7 @@ import pytest from flask import escape from superset import app -from superset.dashboards.dao import DashboardDAO +from superset.daos.dashboard import DashboardDAO from superset.models import core as models from tests.integration_tests.dashboards.base_case import DashboardTestCase from tests.integration_tests.dashboards.consts import * diff --git a/tests/integration_tests/databases/commands_tests.py b/tests/integration_tests/databases/commands_tests.py index b47d3d89fe..8ffb31b782 100644 --- a/tests/integration_tests/databases/commands_tests.py +++ b/tests/integration_tests/databases/commands_tests.py @@ -859,7 +859,7 @@ class TestImportDatabasesCommand(SupersetTestCase): class TestTestConnectionDatabaseCommand(SupersetTestCase): - @patch("superset.databases.dao.Database._get_sqla_engine") + @patch("superset.daos.database.Database._get_sqla_engine") @patch("superset.databases.commands.test_connection.event_logger.log_with_context") @patch("superset.utils.core.g") def test_connection_db_exception( @@ -880,7 +880,7 @@ class TestTestConnectionDatabaseCommand(SupersetTestCase): ) mock_event_logger.assert_called() - @patch("superset.databases.dao.Database._get_sqla_engine") + @patch("superset.daos.database.Database._get_sqla_engine") @patch("superset.databases.commands.test_connection.event_logger.log_with_context") @patch("superset.utils.core.g") def test_connection_do_ping_exception( @@ -925,7 +925,7 @@ class TestTestConnectionDatabaseCommand(SupersetTestCase): == SupersetErrorType.CONNECTION_DATABASE_TIMEOUT ) - @patch("superset.databases.dao.Database._get_sqla_engine") + @patch("superset.daos.database.Database._get_sqla_engine") @patch("superset.databases.commands.test_connection.event_logger.log_with_context") @patch("superset.utils.core.g") def test_connection_superset_security_connection( @@ -948,7 +948,7 @@ class TestTestConnectionDatabaseCommand(SupersetTestCase): mock_event_logger.assert_called() - @patch("superset.databases.dao.Database._get_sqla_engine") + @patch("superset.daos.database.Database._get_sqla_engine") @patch("superset.databases.commands.test_connection.event_logger.log_with_context") @patch("superset.utils.core.g") def test_connection_db_api_exc( @@ -1093,7 +1093,7 @@ def test_validate_partial_invalid_hostname(is_hostname_valid, app_context): class TestTablesDatabaseCommand(SupersetTestCase): - @patch("superset.databases.dao.DatabaseDAO.find_by_id") + @patch("superset.daos.database.DatabaseDAO.find_by_id") def test_database_tables_list_with_unknown_database(self, mock_find_by_id): mock_find_by_id.return_value = None command = TablesDatabaseCommand(1, "test", False) @@ -1102,7 +1102,7 @@ class TestTablesDatabaseCommand(SupersetTestCase): command.run() assert str(excinfo.value) == ("Database not found.") - @patch("superset.databases.dao.DatabaseDAO.find_by_id") + @patch("superset.daos.database.DatabaseDAO.find_by_id") @patch("superset.security.manager.SupersetSecurityManager.can_access_database") @patch("superset.utils.core.g") def test_database_tables_superset_exception( @@ -1121,7 +1121,7 @@ class TestTablesDatabaseCommand(SupersetTestCase): command.run() assert str(excinfo.value) == "Test Error" - @patch("superset.databases.dao.DatabaseDAO.find_by_id") + @patch("superset.daos.database.DatabaseDAO.find_by_id") @patch("superset.security.manager.SupersetSecurityManager.can_access_database") @patch("superset.utils.core.g") def test_database_tables_exception( @@ -1140,7 +1140,7 @@ class TestTablesDatabaseCommand(SupersetTestCase): == "Unexpected error occurred, please check your logs for details" ) - @patch("superset.databases.dao.DatabaseDAO.find_by_id") + @patch("superset.daos.database.DatabaseDAO.find_by_id") @patch("superset.security.manager.SupersetSecurityManager.can_access_database") @patch("superset.utils.core.g") def test_database_tables_list_tables( diff --git a/tests/integration_tests/datasets/api_tests.py b/tests/integration_tests/datasets/api_tests.py index 02ef23f0b8..55fda1af65 100644 --- a/tests/integration_tests/datasets/api_tests.py +++ b/tests/integration_tests/datasets/api_tests.py @@ -30,7 +30,7 @@ from sqlalchemy.sql import func from superset import app from superset.connectors.sqla.models import SqlaTable, SqlMetric, TableColumn -from superset.dao.exceptions import ( +from superset.daos.exceptions import ( DAOCreateFailedError, DAODeleteFailedError, DAOUpdateFailedError, @@ -827,7 +827,7 @@ class TestDatasetApi(SupersetTestCase): rv = self.client.delete(uri) assert rv.status_code == 200 - @patch("superset.datasets.dao.DatasetDAO.create") + @patch("superset.daos.dataset.DatasetDAO.create") def test_create_dataset_sqlalchemy_error(self, mock_dao_create): """ Dataset API: Test create dataset sqlalchemy error @@ -1440,7 +1440,7 @@ class TestDatasetApi(SupersetTestCase): db.session.delete(dataset) db.session.commit() - @patch("superset.datasets.dao.DatasetDAO.update") + @patch("superset.daos.dataset.DatasetDAO.update") def test_update_dataset_sqlalchemy_error(self, mock_dao_update): """ Dataset API: Test update dataset sqlalchemy error @@ -1512,7 +1512,7 @@ class TestDatasetApi(SupersetTestCase): db.session.delete(dataset) db.session.commit() - @patch("superset.datasets.dao.DatasetDAO.delete") + @patch("superset.daos.dataset.DatasetDAO.delete") def test_delete_dataset_sqlalchemy_error(self, mock_dao_delete): """ Dataset API: Test delete dataset sqlalchemy error @@ -1589,7 +1589,7 @@ class TestDatasetApi(SupersetTestCase): assert rv.status_code == 403 @pytest.mark.usefixtures("create_datasets") - @patch("superset.datasets.dao.DatasetDAO.delete") + @patch("superset.daos.dataset.DatasetDAO.delete") def test_delete_dataset_column_fail(self, mock_dao_delete): """ Dataset API: Test delete dataset column @@ -1669,7 +1669,7 @@ class TestDatasetApi(SupersetTestCase): assert rv.status_code == 403 @pytest.mark.usefixtures("create_datasets") - @patch("superset.datasets.dao.DatasetDAO.delete") + @patch("superset.daos.dataset.DatasetDAO.delete") def test_delete_dataset_metric_fail(self, mock_dao_delete): """ Dataset API: Test delete dataset metric diff --git a/tests/integration_tests/datasource/api_tests.py b/tests/integration_tests/datasource/api_tests.py index 522aa33383..b6a6af105d 100644 --- a/tests/integration_tests/datasource/api_tests.py +++ b/tests/integration_tests/datasource/api_tests.py @@ -21,7 +21,7 @@ import pytest from superset import db, security_manager from superset.connectors.sqla.models import SqlaTable -from superset.dao.exceptions import DatasourceTypeNotSupportedError +from superset.daos.exceptions import DatasourceTypeNotSupportedError from tests.integration_tests.base_tests import SupersetTestCase diff --git a/tests/integration_tests/datasource_tests.py b/tests/integration_tests/datasource_tests.py index 2e42c32c8b..b73acc2681 100644 --- a/tests/integration_tests/datasource_tests.py +++ b/tests/integration_tests/datasource_tests.py @@ -26,7 +26,7 @@ from superset import app, db from superset.common.utils.query_cache_manager import QueryCacheManager from superset.connectors.sqla.models import SqlaTable, SqlMetric, TableColumn from superset.constants import CacheRegion -from superset.dao.exceptions import DatasourceNotFound, DatasourceTypeNotSupportedError +from superset.daos.exceptions import DatasourceNotFound, DatasourceTypeNotSupportedError from superset.datasets.commands.exceptions import DatasetNotFoundError from superset.exceptions import SupersetGenericDBErrorException from superset.models.core import Database @@ -433,7 +433,7 @@ class TestDatasource(SupersetTestCase): app.config["DATASET_HEALTH_CHECK"] = None def test_get_datasource_failed(self): - from superset.datasource.dao import DatasourceDAO + from superset.daos.datasource import DatasourceDAO pytest.raises( DatasourceNotFound, @@ -445,7 +445,7 @@ class TestDatasource(SupersetTestCase): self.assertEqual(resp.get("error"), "Datasource does not exist") def test_get_datasource_invalid_datasource_failed(self): - from superset.datasource.dao import DatasourceDAO + from superset.daos.datasource import DatasourceDAO pytest.raises( DatasourceTypeNotSupportedError, diff --git a/tests/integration_tests/embedded/api_tests.py b/tests/integration_tests/embedded/api_tests.py index 8f3950fcf5..113d38166e 100644 --- a/tests/integration_tests/embedded/api_tests.py +++ b/tests/integration_tests/embedded/api_tests.py @@ -21,7 +21,7 @@ from unittest import mock import pytest from superset import db -from superset.embedded.dao import EmbeddedDAO +from superset.daos.dashboard import EmbeddedDashboardDAO from superset.models.dashboard import Dashboard from tests.integration_tests.base_tests import SupersetTestCase from tests.integration_tests.fixtures.birth_names_dashboard import ( @@ -41,7 +41,7 @@ class TestEmbeddedDashboardApi(SupersetTestCase): def test_get_embedded_dashboard(self): self.login("admin") self.dash = db.session.query(Dashboard).filter_by(slug="births").first() - self.embedded = EmbeddedDAO.upsert(self.dash, []) + self.embedded = EmbeddedDashboardDAO.upsert(self.dash, []) uri = f"api/v1/{self.resource_name}/{self.embedded.uuid}" response = self.client.get(uri) self.assert200(response) diff --git a/tests/integration_tests/embedded/dao_tests.py b/tests/integration_tests/embedded/dao_tests.py index 8160144a25..8d62fc0f6d 100644 --- a/tests/integration_tests/embedded/dao_tests.py +++ b/tests/integration_tests/embedded/dao_tests.py @@ -19,7 +19,7 @@ import pytest import tests.integration_tests.test_app # pylint: disable=unused-import from superset import db -from superset.embedded.dao import EmbeddedDAO +from superset.daos.dashboard import EmbeddedDashboardDAO from superset.models.dashboard import Dashboard from tests.integration_tests.base_tests import SupersetTestCase from tests.integration_tests.fixtures.world_bank_dashboard import ( @@ -28,24 +28,24 @@ from tests.integration_tests.fixtures.world_bank_dashboard import ( ) -class TestEmbeddedDAO(SupersetTestCase): +class TestEmbeddedDashboardDAO(SupersetTestCase): @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices") def test_upsert(self): dash = db.session.query(Dashboard).filter_by(slug="world_health").first() assert not dash.embedded - EmbeddedDAO.upsert(dash, ["test.example.com"]) + EmbeddedDashboardDAO.upsert(dash, ["test.example.com"]) assert dash.embedded self.assertEqual(dash.embedded[0].allowed_domains, ["test.example.com"]) original_uuid = dash.embedded[0].uuid self.assertIsNotNone(original_uuid) - EmbeddedDAO.upsert(dash, []) + EmbeddedDashboardDAO.upsert(dash, []) self.assertEqual(dash.embedded[0].allowed_domains, []) self.assertEqual(dash.embedded[0].uuid, original_uuid) @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices") def test_get_by_uuid(self): dash = db.session.query(Dashboard).filter_by(slug="world_health").first() - uuid = str(EmbeddedDAO.upsert(dash, ["test.example.com"]).uuid) + uuid = str(EmbeddedDashboardDAO.upsert(dash, ["test.example.com"]).uuid) db.session.expire_all() - embedded = EmbeddedDAO.find_by_id(uuid) + embedded = EmbeddedDashboardDAO.find_by_id(uuid) self.assertIsNotNone(embedded) diff --git a/tests/integration_tests/embedded/test_view.py b/tests/integration_tests/embedded/test_view.py index 9f524e9c09..1b3248883f 100644 --- a/tests/integration_tests/embedded/test_view.py +++ b/tests/integration_tests/embedded/test_view.py @@ -22,7 +22,7 @@ from unittest import mock import pytest from superset import db -from superset.embedded.dao import EmbeddedDAO +from superset.daos.dashboard import EmbeddedDashboardDAO from superset.models.dashboard import Dashboard from tests.integration_tests.fixtures.birth_names_dashboard import ( load_birth_names_dashboard_with_slices, @@ -43,7 +43,7 @@ if TYPE_CHECKING: ) def test_get_embedded_dashboard(client: FlaskClient[Any]): dash = db.session.query(Dashboard).filter_by(slug="births").first() - embedded = EmbeddedDAO.upsert(dash, []) + embedded = EmbeddedDashboardDAO.upsert(dash, []) uri = f"embedded/{embedded.uuid}" response = client.get(uri) assert response.status_code == 200 @@ -56,7 +56,7 @@ def test_get_embedded_dashboard(client: FlaskClient[Any]): ) def test_get_embedded_dashboard_referrer_not_allowed(client: FlaskClient[Any]): dash = db.session.query(Dashboard).filter_by(slug="births").first() - embedded = EmbeddedDAO.upsert(dash, ["test.example.com"]) + embedded = EmbeddedDashboardDAO.upsert(dash, ["test.example.com"]) uri = f"embedded/{embedded.uuid}" response = client.get(uri) assert response.status_code == 403 diff --git a/tests/integration_tests/explore/api_tests.py b/tests/integration_tests/explore/api_tests.py index af5bd88137..50606257c2 100644 --- a/tests/integration_tests/explore/api_tests.py +++ b/tests/integration_tests/explore/api_tests.py @@ -216,7 +216,7 @@ def test_get_dataset_access_denied( assert data["message"] == message -@patch("superset.datasource.dao.DatasourceDAO.get_datasource") +@patch("superset.daos.datasource.DatasourceDAO.get_datasource") def test_wrong_endpoint(mock_get_datasource, test_client, login_as_admin, dataset): dataset.default_endpoint = "another_endpoint" mock_get_datasource.return_value = dataset diff --git a/tests/integration_tests/query_context_tests.py b/tests/integration_tests/query_context_tests.py index 7a3d4e4a1e..8c2082d1c4 100644 --- a/tests/integration_tests/query_context_tests.py +++ b/tests/integration_tests/query_context_tests.py @@ -30,7 +30,7 @@ from superset.common.query_context import QueryContext from superset.common.query_context_factory import QueryContextFactory from superset.common.query_object import QueryObject from superset.connectors.sqla.models import SqlMetric -from superset.datasource.dao import DatasourceDAO +from superset.daos.datasource import DatasourceDAO from superset.extensions import cache_manager from superset.superset_typing import AdhocColumn from superset.utils.core import ( diff --git a/tests/integration_tests/reports/commands_tests.py b/tests/integration_tests/reports/commands_tests.py index db80079d77..120559f8fd 100644 --- a/tests/integration_tests/reports/commands_tests.py +++ b/tests/integration_tests/reports/commands_tests.py @@ -1955,7 +1955,7 @@ def test_grace_period_error_flap( @pytest.mark.usefixtures( "load_birth_names_dashboard_with_slices", "create_report_email_dashboard" ) -@patch("superset.reports.dao.ReportScheduleDAO.bulk_delete_logs") +@patch("superset.daos.report.ReportScheduleDAO.bulk_delete_logs") def test_prune_log_soft_time_out(bulk_delete_logs, create_report_email_dashboard): from celery.exceptions import SoftTimeLimitExceeded diff --git a/tests/integration_tests/security/api_tests.py b/tests/integration_tests/security/api_tests.py index 9a5a085c81..2462803f21 100644 --- a/tests/integration_tests/security/api_tests.py +++ b/tests/integration_tests/security/api_tests.py @@ -23,7 +23,7 @@ import pytest from flask_wtf.csrf import generate_csrf from superset import db -from superset.embedded.dao import EmbeddedDAO +from superset.daos.dashboard import EmbeddedDashboardDAO from superset.models.dashboard import Dashboard from superset.utils.urls import get_url_host from tests.integration_tests.base_tests import SupersetTestCase @@ -89,7 +89,7 @@ class TestSecurityGuestTokenApi(SupersetTestCase): @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices") def test_post_guest_token_authorized(self): self.dash = db.session.query(Dashboard).filter_by(slug="births").first() - self.embedded = EmbeddedDAO.upsert(self.dash, []) + self.embedded = EmbeddedDashboardDAO.upsert(self.dash, []) self.login(username="admin") user = {"username": "bob", "first_name": "Bob", "last_name": "Also Bob"} resource = {"type": "dashboard", "id": str(self.embedded.uuid)} diff --git a/tests/integration_tests/security/guest_token_security_tests.py b/tests/integration_tests/security/guest_token_security_tests.py index 78bd8bde86..86d02975d0 100644 --- a/tests/integration_tests/security/guest_token_security_tests.py +++ b/tests/integration_tests/security/guest_token_security_tests.py @@ -21,8 +21,8 @@ import pytest from flask import g from superset import db, security_manager +from superset.daos.dashboard import EmbeddedDashboardDAO from superset.dashboards.commands.exceptions import DashboardAccessDeniedError -from superset.embedded.dao import EmbeddedDAO from superset.exceptions import SupersetSecurityException from superset.models.dashboard import Dashboard from superset.security.guest_token import GuestTokenResourceType @@ -100,7 +100,7 @@ class TestGuestUserSecurity(SupersetTestCase): class TestGuestUserDashboardAccess(SupersetTestCase): def setUp(self) -> None: self.dash = db.session.query(Dashboard).filter_by(slug="births").first() - self.embedded = EmbeddedDAO.upsert(self.dash, []) + self.embedded = EmbeddedDashboardDAO.upsert(self.dash, []) self.authorized_guest = security_manager.get_guest_user_from_token( { "user": {}, diff --git a/tests/integration_tests/security_tests.py b/tests/integration_tests/security_tests.py index 17a6a78548..fe19944387 100644 --- a/tests/integration_tests/security_tests.py +++ b/tests/integration_tests/security_tests.py @@ -29,7 +29,7 @@ import pytest from flask import current_app from flask_appbuilder.security.sqla.models import Role -from superset.datasource.dao import DatasourceDAO +from superset.daos.datasource import DatasourceDAO from superset.models.dashboard import Dashboard from superset import app, appbuilder, db, security_manager, viz from superset.connectors.sqla.models import SqlaTable diff --git a/tests/integration_tests/tags/dao_tests.py b/tests/integration_tests/tags/dao_tests.py index 49b22d260b..8acaa353e9 100644 --- a/tests/integration_tests/tags/dao_tests.py +++ b/tests/integration_tests/tags/dao_tests.py @@ -18,17 +18,17 @@ from operator import and_ from unittest.mock import patch import pytest -from superset.dao.exceptions import DAOCreateFailedError, DAOException +from superset.daos.exceptions import DAOCreateFailedError, DAOException from superset.models.slice import Slice from superset.models.sql_lab import SavedQuery -from superset.tags.dao import TagDAO +from superset.daos.tag import TagDAO from superset.tags.exceptions import InvalidTagNameError from superset.tags.models import ObjectTypes, Tag, TaggedObject from tests.integration_tests.tags.api_tests import TAGS_FIXTURE_COUNT import tests.integration_tests.test_app # pylint: disable=unused-import from superset import db, security_manager -from superset.dashboards.dao import DashboardDAO +from superset.daos.dashboard import DashboardDAO from superset.models.dashboard import Dashboard from tests.integration_tests.base_tests import SupersetTestCase from tests.integration_tests.fixtures.world_bank_dashboard import ( diff --git a/tests/unit_tests/charts/dao/dao_tests.py b/tests/unit_tests/charts/dao/dao_tests.py index b1d5cc6488..e8c58b5600 100644 --- a/tests/unit_tests/charts/dao/dao_tests.py +++ b/tests/unit_tests/charts/dao/dao_tests.py @@ -45,7 +45,7 @@ def session_with_data(session: Session) -> Iterator[Session]: def test_slice_find_by_id_skip_base_filter(session_with_data: Session) -> None: - from superset.charts.dao import ChartDAO + from superset.daos.chart import ChartDAO from superset.models.slice import Slice result = ChartDAO.find_by_id(1, session=session_with_data, skip_base_filter=True) @@ -59,7 +59,7 @@ def test_slice_find_by_id_skip_base_filter(session_with_data: Session) -> None: def test_datasource_find_by_id_skip_base_filter_not_found( session_with_data: Session, ) -> None: - from superset.charts.dao import ChartDAO + from superset.daos.chart import ChartDAO result = ChartDAO.find_by_id( 125326326, session=session_with_data, skip_base_filter=True @@ -68,7 +68,7 @@ def test_datasource_find_by_id_skip_base_filter_not_found( def test_add_favorite(session_with_data: Session) -> None: - from superset.charts.dao import ChartDAO + from superset.daos.chart import ChartDAO chart = ChartDAO.find_by_id(1, session=session_with_data, skip_base_filter=True) if not chart: @@ -83,7 +83,7 @@ def test_add_favorite(session_with_data: Session) -> None: def test_remove_favorite(session_with_data: Session) -> None: - from superset.charts.dao import ChartDAO + from superset.daos.chart import ChartDAO chart = ChartDAO.find_by_id(1, session=session_with_data, skip_base_filter=True) if not chart: diff --git a/tests/unit_tests/dao/queries_test.py b/tests/unit_tests/dao/queries_test.py index d0ab3ec8a5..65e9bbfbfb 100644 --- a/tests/unit_tests/dao/queries_test.py +++ b/tests/unit_tests/dao/queries_test.py @@ -51,7 +51,7 @@ def test_query_dao_save_metadata(session: Session) -> None: session.add(db) session.add(query_obj) - from superset.queries.dao import QueryDAO + from superset.daos.query import QueryDAO query = session.query(Query).one() QueryDAO.save_metadata(query=query, payload={"columns": []}) @@ -105,7 +105,7 @@ def test_query_dao_get_queries_changed_after(session: Session) -> None: session.add(old_query_obj) session.add(updated_query_obj) - from superset.queries.dao import QueryDAO + from superset.daos.query import QueryDAO timestamp = datetime.timestamp(now - timedelta(days=2)) * 1000 result = QueryDAO.get_queries_changed_after(timestamp) @@ -146,7 +146,7 @@ def test_query_dao_stop_query_not_found( mocker.patch("superset.sql_lab.cancel_query", return_value=False) - from superset.queries.dao import QueryDAO + from superset.daos.query import QueryDAO with pytest.raises(QueryNotFoundException): QueryDAO.stop_query("foo2") @@ -186,7 +186,7 @@ def test_query_dao_stop_query_not_running( session.add(db) session.add(query_obj) - from superset.queries.dao import QueryDAO + from superset.daos.query import QueryDAO QueryDAO.stop_query(query_obj.client_id) query = session.query(Query).one() @@ -226,7 +226,7 @@ def test_query_dao_stop_query_failed( mocker.patch("superset.sql_lab.cancel_query", return_value=False) - from superset.queries.dao import QueryDAO + from superset.daos.query import QueryDAO with pytest.raises(SupersetCancelQueryException): QueryDAO.stop_query(query_obj.client_id) @@ -266,7 +266,7 @@ def test_query_dao_stop_query(mocker: MockFixture, app: Any, session: Session) - mocker.patch("superset.sql_lab.cancel_query", return_value=True) - from superset.queries.dao import QueryDAO + from superset.daos.query import QueryDAO QueryDAO.stop_query(query_obj.client_id) query = session.query(Query).one() diff --git a/tests/unit_tests/dashboards/dao_tests.py b/tests/unit_tests/dashboards/dao_tests.py index c94d2ab157..3bf4038f16 100644 --- a/tests/unit_tests/dashboards/dao_tests.py +++ b/tests/unit_tests/dashboards/dao_tests.py @@ -43,7 +43,7 @@ def session_with_data(session: Session) -> Iterator[Session]: def test_add_favorite(session_with_data: Session) -> None: - from superset.dashboards.dao import DashboardDAO + from superset.daos.dashboard import DashboardDAO dashboard = DashboardDAO.find_by_id( 100, session=session_with_data, skip_base_filter=True @@ -60,7 +60,7 @@ def test_add_favorite(session_with_data: Session) -> None: def test_remove_favorite(session_with_data: Session) -> None: - from superset.dashboards.dao import DashboardDAO + from superset.daos.dashboard import DashboardDAO dashboard = DashboardDAO.find_by_id( 100, session=session_with_data, skip_base_filter=True diff --git a/tests/unit_tests/databases/api_test.py b/tests/unit_tests/databases/api_test.py index 342920bd17..24fde88369 100644 --- a/tests/unit_tests/databases/api_test.py +++ b/tests/unit_tests/databases/api_test.py @@ -356,8 +356,8 @@ def test_delete_ssh_tunnel( Test that we can delete SSH Tunnel """ with app.app_context(): + from superset.daos.database import DatabaseDAO from superset.databases.api import DatabaseRestApi - from superset.databases.dao import DatabaseDAO from superset.databases.ssh_tunnel.models import SSHTunnel from superset.models.core import Database @@ -432,8 +432,8 @@ def test_delete_ssh_tunnel_not_found( Test that we cannot delete a tunnel that does not exist """ with app.app_context(): + from superset.daos.database import DatabaseDAO from superset.databases.api import DatabaseRestApi - from superset.databases.dao import DatabaseDAO from superset.databases.ssh_tunnel.models import SSHTunnel from superset.models.core import Database diff --git a/tests/unit_tests/databases/dao/dao_tests.py b/tests/unit_tests/databases/dao/dao_tests.py index f085cb53c7..b792a65336 100644 --- a/tests/unit_tests/databases/dao/dao_tests.py +++ b/tests/unit_tests/databases/dao/dao_tests.py @@ -51,7 +51,7 @@ def session_with_data(session: Session) -> Iterator[Session]: def test_database_get_ssh_tunnel(session_with_data: Session) -> None: - from superset.databases.dao import DatabaseDAO + from superset.daos.database import DatabaseDAO from superset.databases.ssh_tunnel.models import SSHTunnel result = DatabaseDAO.get_ssh_tunnel(1) @@ -62,7 +62,7 @@ def test_database_get_ssh_tunnel(session_with_data: Session) -> None: def test_database_get_ssh_tunnel_not_found(session_with_data: Session) -> None: - from superset.databases.dao import DatabaseDAO + from superset.daos.database import DatabaseDAO result = DatabaseDAO.get_ssh_tunnel(2) diff --git a/tests/unit_tests/databases/ssh_tunnel/commands/delete_test.py b/tests/unit_tests/databases/ssh_tunnel/commands/delete_test.py index de0b70db9c..641e34d347 100644 --- a/tests/unit_tests/databases/ssh_tunnel/commands/delete_test.py +++ b/tests/unit_tests/databases/ssh_tunnel/commands/delete_test.py @@ -54,7 +54,7 @@ def session_with_data(session: Session) -> Iterator[Session]: def test_delete_ssh_tunnel_command( mocker: MockFixture, session_with_data: Session ) -> None: - from superset.databases.dao import DatabaseDAO + from superset.daos.database import DatabaseDAO from superset.databases.ssh_tunnel.commands.delete import DeleteSSHTunnelCommand from superset.databases.ssh_tunnel.models import SSHTunnel diff --git a/tests/unit_tests/databases/ssh_tunnel/commands/update_test.py b/tests/unit_tests/databases/ssh_tunnel/commands/update_test.py index 544cf3434a..d4a5faba8b 100644 --- a/tests/unit_tests/databases/ssh_tunnel/commands/update_test.py +++ b/tests/unit_tests/databases/ssh_tunnel/commands/update_test.py @@ -50,7 +50,7 @@ def session_with_data(session: Session) -> Iterator[Session]: def test_update_shh_tunnel_command(session_with_data: Session) -> None: - from superset.databases.dao import DatabaseDAO + from superset.daos.database import DatabaseDAO from superset.databases.ssh_tunnel.commands.update import UpdateSSHTunnelCommand from superset.databases.ssh_tunnel.models import SSHTunnel @@ -72,7 +72,7 @@ def test_update_shh_tunnel_command(session_with_data: Session) -> None: def test_update_shh_tunnel_invalid_params(session_with_data: Session) -> None: - from superset.databases.dao import DatabaseDAO + from superset.daos.database import DatabaseDAO from superset.databases.ssh_tunnel.commands.update import UpdateSSHTunnelCommand from superset.databases.ssh_tunnel.models import SSHTunnel diff --git a/tests/unit_tests/databases/ssh_tunnel/dao_tests.py b/tests/unit_tests/databases/ssh_tunnel/dao_tests.py index 27f9c3b8ad..af0b1ac001 100644 --- a/tests/unit_tests/databases/ssh_tunnel/dao_tests.py +++ b/tests/unit_tests/databases/ssh_tunnel/dao_tests.py @@ -21,8 +21,7 @@ from sqlalchemy.orm.session import Session def test_create_ssh_tunnel(): - from superset.databases.dao import DatabaseDAO - from superset.databases.ssh_tunnel.dao import SSHTunnelDAO + from superset.daos.database import DatabaseDAO, SSHTunnelDAO from superset.databases.ssh_tunnel.models import SSHTunnel from superset.models.core import Database diff --git a/tests/unit_tests/datasets/dao/dao_tests.py b/tests/unit_tests/datasets/dao/dao_tests.py index 4eb43cd9de..3302f2dc04 100644 --- a/tests/unit_tests/datasets/dao/dao_tests.py +++ b/tests/unit_tests/datasets/dao/dao_tests.py @@ -46,7 +46,7 @@ def session_with_data(session: Session) -> Iterator[Session]: def test_datasource_find_by_id_skip_base_filter(session_with_data: Session) -> None: from superset.connectors.sqla.models import SqlaTable - from superset.datasets.dao import DatasetDAO + from superset.daos.dataset import DatasetDAO result = DatasetDAO.find_by_id( 1, @@ -63,7 +63,7 @@ def test_datasource_find_by_id_skip_base_filter(session_with_data: Session) -> N def test_datasource_find_by_id_skip_base_filter_not_found( session_with_data: Session, ) -> None: - from superset.datasets.dao import DatasetDAO + from superset.daos.dataset import DatasetDAO result = DatasetDAO.find_by_id( 125326326, @@ -75,7 +75,7 @@ def test_datasource_find_by_id_skip_base_filter_not_found( def test_datasource_find_by_ids_skip_base_filter(session_with_data: Session) -> None: from superset.connectors.sqla.models import SqlaTable - from superset.datasets.dao import DatasetDAO + from superset.daos.dataset import DatasetDAO result = DatasetDAO.find_by_ids( [1, 125326326], @@ -92,7 +92,7 @@ def test_datasource_find_by_ids_skip_base_filter(session_with_data: Session) -> def test_datasource_find_by_ids_skip_base_filter_not_found( session_with_data: Session, ) -> None: - from superset.datasets.dao import DatasetDAO + from superset.daos.dataset import DatasetDAO result = DatasetDAO.find_by_ids( [125326326, 125326326125326326], diff --git a/tests/unit_tests/datasource/dao_tests.py b/tests/unit_tests/datasource/dao_tests.py index 99a4850301..0af2cbf020 100644 --- a/tests/unit_tests/datasource/dao_tests.py +++ b/tests/unit_tests/datasource/dao_tests.py @@ -101,7 +101,7 @@ FROM my_catalog.my_schema.my_table def test_get_datasource_sqlatable(session_with_data: Session) -> None: from superset.connectors.sqla.models import SqlaTable - from superset.datasource.dao import DatasourceDAO + from superset.daos.datasource import DatasourceDAO result = DatasourceDAO.get_datasource( datasource_type=DatasourceType.TABLE, @@ -115,7 +115,7 @@ def test_get_datasource_sqlatable(session_with_data: Session) -> None: def test_get_datasource_query(session_with_data: Session) -> None: - from superset.datasource.dao import DatasourceDAO + from superset.daos.datasource import DatasourceDAO from superset.models.sql_lab import Query result = DatasourceDAO.get_datasource( @@ -127,7 +127,7 @@ def test_get_datasource_query(session_with_data: Session) -> None: def test_get_datasource_saved_query(session_with_data: Session) -> None: - from superset.datasource.dao import DatasourceDAO + from superset.daos.datasource import DatasourceDAO from superset.models.sql_lab import SavedQuery result = DatasourceDAO.get_datasource( @@ -141,7 +141,7 @@ def test_get_datasource_saved_query(session_with_data: Session) -> None: def test_get_datasource_sl_table(session_with_data: Session) -> None: - from superset.datasource.dao import DatasourceDAO + from superset.daos.datasource import DatasourceDAO from superset.tables.models import Table result = DatasourceDAO.get_datasource( @@ -155,8 +155,8 @@ def test_get_datasource_sl_table(session_with_data: Session) -> None: def test_get_datasource_sl_dataset(session_with_data: Session) -> None: + from superset.daos.datasource import DatasourceDAO from superset.datasets.models import Dataset - from superset.datasource.dao import DatasourceDAO result = DatasourceDAO.get_datasource( datasource_type=DatasourceType.DATASET, @@ -170,8 +170,8 @@ def test_get_datasource_sl_dataset(session_with_data: Session) -> None: def test_get_datasource_w_str_param(session_with_data: Session) -> None: from superset.connectors.sqla.models import SqlaTable + from superset.daos.datasource import DatasourceDAO from superset.datasets.models import Dataset - from superset.datasource.dao import DatasourceDAO from superset.tables.models import Table assert isinstance( @@ -201,8 +201,8 @@ def test_get_all_datasources(session_with_data: Session) -> None: def test_not_found_datasource(session_with_data: Session) -> None: - from superset.dao.exceptions import DatasourceNotFound - from superset.datasource.dao import DatasourceDAO + from superset.daos.datasource import DatasourceDAO + from superset.daos.exceptions import DatasourceNotFound with pytest.raises(DatasourceNotFound): DatasourceDAO.get_datasource( diff --git a/tests/unit_tests/explore/utils_test.py b/tests/unit_tests/explore/utils_test.py index b2989b1244..de39187ec7 100644 --- a/tests/unit_tests/explore/utils_test.py +++ b/tests/unit_tests/explore/utils_test.py @@ -35,9 +35,9 @@ from superset.datasets.commands.exceptions import ( from superset.exceptions import SupersetSecurityException from superset.utils.core import DatasourceType, override_user -dataset_find_by_id = "superset.datasets.dao.DatasetDAO.find_by_id" -query_find_by_id = "superset.queries.dao.QueryDAO.find_by_id" -chart_find_by_id = "superset.charts.dao.ChartDAO.find_by_id" +dataset_find_by_id = "superset.daos.dataset.DatasetDAO.find_by_id" +query_find_by_id = "superset.daos.query.QueryDAO.find_by_id" +chart_find_by_id = "superset.daos.chart.ChartDAO.find_by_id" is_admin = "superset.security.SupersetSecurityManager.is_admin" is_owner = "superset.security.SupersetSecurityManager.is_owner" can_access_datasource = ( diff --git a/tests/unit_tests/jinja_context_test.py b/tests/unit_tests/jinja_context_test.py index 3478a9e3f0..fe4b144d2f 100644 --- a/tests/unit_tests/jinja_context_test.py +++ b/tests/unit_tests/jinja_context_test.py @@ -83,7 +83,7 @@ def test_dataset_macro(mocker: MockFixture) -> None: schema_perm=None, extra=json.dumps({"warning_markdown": "*WARNING*"}), ) - DatasetDAO = mocker.patch("superset.datasets.dao.DatasetDAO") + DatasetDAO = mocker.patch("superset.daos.dataset.DatasetDAO") DatasetDAO.find_by_id.return_value = dataset assert ( @@ -143,7 +143,7 @@ def test_dataset_macro_mutator_with_comments(mocker: MockFixture) -> None: """ return f"-- begin\n{sql}\n-- end" - DatasetDAO = mocker.patch("superset.datasets.dao.DatasetDAO") + DatasetDAO = mocker.patch("superset.daos.dataset.DatasetDAO") DatasetDAO.find_by_id().get_query_str_extended().sql = mutator("SELECT 1") assert ( dataset_macro(1)