mirror of https://github.com/apache/superset.git
chore: Allow only iterables for BaseDAO.delete() (#25844)
This commit is contained in:
parent
260d561b9a
commit
843c7ab58a
|
@ -16,7 +16,7 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Any, cast, Generic, get_args, TypeVar
|
from typing import Any, Generic, get_args, TypeVar
|
||||||
|
|
||||||
from flask_appbuilder.models.filters import BaseFilter
|
from flask_appbuilder.models.filters import BaseFilter
|
||||||
from flask_appbuilder.models.sqla import Model
|
from flask_appbuilder.models.sqla import Model
|
||||||
|
@ -30,7 +30,6 @@ from superset.daos.exceptions import (
|
||||||
DAOUpdateFailedError,
|
DAOUpdateFailedError,
|
||||||
)
|
)
|
||||||
from superset.extensions import db
|
from superset.extensions import db
|
||||||
from superset.utils.core import as_list
|
|
||||||
|
|
||||||
T = TypeVar("T", bound=Model)
|
T = TypeVar("T", bound=Model)
|
||||||
|
|
||||||
|
@ -197,9 +196,9 @@ class BaseDAO(Generic[T]):
|
||||||
return item # type: ignore
|
return item # type: ignore
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def delete(cls, item_or_items: T | list[T], commit: bool = True) -> None:
|
def delete(cls, items: list[T], commit: bool = True) -> None:
|
||||||
"""
|
"""
|
||||||
Delete the specified item(s) including their associated relationships.
|
Delete the specified items including their associated relationships.
|
||||||
|
|
||||||
Note that bulk deletion via `delete` is not invoked in the base class as this
|
Note that bulk deletion via `delete` is not invoked in the base class as this
|
||||||
does not dispatch the ORM `after_delete` event which may be required to augment
|
does not dispatch the ORM `after_delete` event which may be required to augment
|
||||||
|
@ -209,12 +208,12 @@ class BaseDAO(Generic[T]):
|
||||||
Subclasses may invoke bulk deletion but are responsible for instrumenting any
|
Subclasses may invoke bulk deletion but are responsible for instrumenting any
|
||||||
post-deletion logic.
|
post-deletion logic.
|
||||||
|
|
||||||
:param items: The item(s) to delete
|
:param items: The items to delete
|
||||||
:param commit: Whether to commit the transaction
|
:param commit: Whether to commit the transaction
|
||||||
:raises DAODeleteFailedError: If the deletion failed
|
:raises DAODeleteFailedError: If the deletion failed
|
||||||
:see: https://docs.sqlalchemy.org/en/latest/orm/queryguide/dml.html
|
:see: https://docs.sqlalchemy.org/en/latest/orm/queryguide/dml.html
|
||||||
"""
|
"""
|
||||||
items = cast(list[T], as_list(item_or_items))
|
|
||||||
try:
|
try:
|
||||||
for item in items:
|
for item in items:
|
||||||
db.session.delete(item)
|
db.session.delete(item)
|
||||||
|
|
|
@ -1349,8 +1349,7 @@ class DashboardRestApi(BaseSupersetModelRestApi):
|
||||||
500:
|
500:
|
||||||
$ref: '#/components/responses/500'
|
$ref: '#/components/responses/500'
|
||||||
"""
|
"""
|
||||||
for embedded in dashboard.embedded:
|
EmbeddedDashboardDAO.delete(dashboard.embedded)
|
||||||
EmbeddedDashboardDAO.delete(embedded)
|
|
||||||
return self.response(200, message="OK")
|
return self.response(200, message="OK")
|
||||||
|
|
||||||
@expose("/<id_or_slug>/copy/", methods=("POST",))
|
@expose("/<id_or_slug>/copy/", methods=("POST",))
|
||||||
|
|
|
@ -38,7 +38,7 @@ class DeleteFilterSetCommand(BaseFilterSetCommand):
|
||||||
assert self._filter_set
|
assert self._filter_set
|
||||||
|
|
||||||
try:
|
try:
|
||||||
FilterSetDAO.delete(self._filter_set)
|
FilterSetDAO.delete([self._filter_set])
|
||||||
except DAODeleteFailedError as err:
|
except DAODeleteFailedError as err:
|
||||||
raise FilterSetDeleteFailedError(str(self._filter_set_id), "") from err
|
raise FilterSetDeleteFailedError(str(self._filter_set_id), "") from err
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ class DeleteDatabaseCommand(BaseCommand):
|
||||||
assert self._model
|
assert self._model
|
||||||
|
|
||||||
try:
|
try:
|
||||||
DatabaseDAO.delete(self._model)
|
DatabaseDAO.delete([self._model])
|
||||||
except DAODeleteFailedError as ex:
|
except DAODeleteFailedError as ex:
|
||||||
logger.exception(ex.exception)
|
logger.exception(ex.exception)
|
||||||
raise DatabaseDeleteFailedError() from ex
|
raise DatabaseDeleteFailedError() from ex
|
||||||
|
|
|
@ -43,7 +43,7 @@ class DeleteSSHTunnelCommand(BaseCommand):
|
||||||
assert self._model
|
assert self._model
|
||||||
|
|
||||||
try:
|
try:
|
||||||
SSHTunnelDAO.delete(self._model)
|
SSHTunnelDAO.delete([self._model])
|
||||||
except DAODeleteFailedError as ex:
|
except DAODeleteFailedError as ex:
|
||||||
raise SSHTunnelDeleteFailedError() from ex
|
raise SSHTunnelDeleteFailedError() from ex
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ class DeleteDatasetColumnCommand(BaseCommand):
|
||||||
assert self._model
|
assert self._model
|
||||||
|
|
||||||
try:
|
try:
|
||||||
DatasetColumnDAO.delete(self._model)
|
DatasetColumnDAO.delete([self._model])
|
||||||
except DAODeleteFailedError as ex:
|
except DAODeleteFailedError as ex:
|
||||||
logger.exception(ex.exception)
|
logger.exception(ex.exception)
|
||||||
raise DatasetColumnDeleteFailedError() from ex
|
raise DatasetColumnDeleteFailedError() from ex
|
||||||
|
|
|
@ -43,7 +43,7 @@ class DeleteDatasetMetricCommand(BaseCommand):
|
||||||
assert self._model
|
assert self._model
|
||||||
|
|
||||||
try:
|
try:
|
||||||
DatasetMetricDAO.delete(self._model)
|
DatasetMetricDAO.delete([self._model])
|
||||||
except DAODeleteFailedError as ex:
|
except DAODeleteFailedError as ex:
|
||||||
logger.exception(ex.exception)
|
logger.exception(ex.exception)
|
||||||
raise DatasetMetricDeleteFailedError() from ex
|
raise DatasetMetricDeleteFailedError() from ex
|
||||||
|
|
|
@ -192,4 +192,4 @@ class TestDashboardDatasetSecurity(DashboardTestCase):
|
||||||
self.assert200(rv)
|
self.assert200(rv)
|
||||||
data = json.loads(rv.data.decode("utf-8"))
|
data = json.loads(rv.data.decode("utf-8"))
|
||||||
self.assertEqual(0, data["count"])
|
self.assertEqual(0, data["count"])
|
||||||
DashboardDAO.delete(dashboard)
|
DashboardDAO.delete([dashboard])
|
||||||
|
|
Loading…
Reference in New Issue