diff --git a/superset/daos/chart.py b/superset/daos/chart.py index f82239bfc0996..7eae38cb0ecad 100644 --- a/superset/daos/chart.py +++ b/superset/daos/chart.py @@ -20,14 +20,12 @@ from datetime import datetime from typing import TYPE_CHECKING -from sqlalchemy.exc import SQLAlchemyError - from superset.charts.filters import ChartFilter from superset.daos.base import BaseDAO from superset.extensions import db from superset.models.core import FavStar, FavStarClassName from superset.models.slice import Slice -from superset.utils.core import get_iterable, get_user_id +from superset.utils.core import get_user_id if TYPE_CHECKING: from superset.connectors.base.models import BaseDatasource @@ -38,21 +36,6 @@ class ChartDAO(BaseDAO[Slice]): base_filter = ChartFilter - @classmethod - def delete(cls, items: Slice | list[Slice], commit: bool = True) -> None: - item_ids = [item.id for item in get_iterable(items)] - # bulk delete, first delete related data - # bulk delete itself - try: - db.session.query(Slice).filter(Slice.id.in_(item_ids)).delete( - synchronize_session="fetch" - ) - if commit: - db.session.commit() - except SQLAlchemyError as ex: - db.session.rollback() - raise ex - @staticmethod def favorited_ids(charts: list[Slice]) -> list[FavStar]: ids = [chart.id for chart in charts] diff --git a/superset/daos/dashboard.py b/superset/daos/dashboard.py index 1b62041cc4592..e6fe6ff25d6c8 100644 --- a/superset/daos/dashboard.py +++ b/superset/daos/dashboard.py @@ -23,7 +23,6 @@ from flask import g from flask_appbuilder.models.sqla.interface import SQLAInterface -from sqlalchemy.exc import SQLAlchemyError from superset import is_feature_enabled, security_manager from superset.daos.base import BaseDAO @@ -48,7 +47,7 @@ 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_iterable, get_user_id +from superset.utils.core import get_user_id from superset.utils.dashboard_filter_scopes_converter import copy_filter_scopes logger = logging.getLogger(__name__) @@ -190,19 +189,6 @@ def update_charts_owners(model: Dashboard, commit: bool = True) -> Dashboard: db.session.commit() return model - @classmethod - def delete(cls, items: Dashboard | list[Dashboard], commit: bool = True) -> None: - item_ids = [item.id for item in get_iterable(items)] - try: - db.session.query(Dashboard).filter(Dashboard.id.in_(item_ids)).delete( - synchronize_session="fetch" - ) - if commit: - db.session.commit() - except SQLAlchemyError as ex: - db.session.rollback() - raise ex - @staticmethod def set_dash_metadata( # pylint: disable=too-many-locals dashboard: Dashboard, diff --git a/superset/daos/dataset.py b/superset/daos/dataset.py index 5589f05de95c2..8f12fcca9375a 100644 --- a/superset/daos/dataset.py +++ b/superset/daos/dataset.py @@ -21,20 +21,19 @@ from sqlalchemy.exc import SQLAlchemyError -from superset import security_manager from superset.connectors.sqla.models import SqlaTable, SqlMetric, TableColumn from superset.daos.base import BaseDAO from superset.extensions import db from superset.models.core import Database from superset.models.dashboard import Dashboard from superset.models.slice import Slice -from superset.utils.core import DatasourceType, get_iterable +from superset.utils.core import DatasourceType from superset.views.base import DatasourceFilter logger = logging.getLogger(__name__) -class DatasetDAO(BaseDAO[SqlaTable]): # pylint: disable=too-many-public-methods +class DatasetDAO(BaseDAO[SqlaTable]): base_filter = DatasourceFilter @staticmethod @@ -309,42 +308,6 @@ def find_dataset_metric(cls, dataset_id: int, metric_id: int) -> SqlMetric | Non return None return db.session.query(SqlMetric).get(metric_id) - @classmethod - def delete( - cls, - items: SqlaTable | list[SqlaTable], - commit: bool = True, - ) -> None: - """ - Delete the specified items(s) including their associated relationships. - - Note that bulk deletion via `delete` does not dispatch the `after_delete` event - and thus the ORM event listener callback needs to be invoked manually. - - :param items: The item(s) to delete - :param commit: Whether to commit the transaction - :raises DAODeleteFailedError: If the deletion failed - :see: https://docs.sqlalchemy.org/en/latest/orm/queryguide/dml.html - """ - - try: - db.session.query(SqlaTable).filter( - SqlaTable.id.in_(item.id for item in get_iterable(items)) - ).delete(synchronize_session="fetch") - - connection = db.session.connection() - mapper = next(iter(cls.model_cls.registry.mappers)) # type: ignore - - for item in get_iterable(items): - security_manager.dataset_after_delete(mapper, connection, item) - - if commit: - db.session.commit() - except SQLAlchemyError as ex: - if commit: - db.session.rollback() - raise ex - @staticmethod def get_table_by_name(database_id: int, table_name: str) -> SqlaTable | None: return ( diff --git a/tests/integration_tests/datasets/api_tests.py b/tests/integration_tests/datasets/api_tests.py index 027002507aece..5e0c23ced6053 100644 --- a/tests/integration_tests/datasets/api_tests.py +++ b/tests/integration_tests/datasets/api_tests.py @@ -25,6 +25,7 @@ import prison import pytest import yaml +from sqlalchemy import inspect from sqlalchemy.orm import joinedload from sqlalchemy.sql import func @@ -153,7 +154,9 @@ def create_datasets(self): # rollback changes for dataset in datasets: - db.session.delete(dataset) + state = inspect(dataset) + if not state.was_deleted: + db.session.delete(dataset) db.session.commit() @staticmethod