apache/superset · error · DatabaseDeleteDatasetsExistFailedError
Cannot delete a database that has datasets attached
Error message
Cannot delete a database that has datasets attached
What it means
DatabaseDeleteDatasetsExistFailedError ('Cannot delete a database that has datasets attached') raised in DeleteDatabaseCommand.validate (delete.py:100) when the visibility-filter-bypassing count finds at least one LIVE (non-soft-deleted) SqlaTable row with database_id == self._model_id. The explicit EXISTS queries are there precisely because the ORM relationship would hide soft-deleted datasets; has_live being true means ordinary, visible datasets still reference the database.
Source
Thrown at superset/commands/database/delete.py:100
with skip_visibility_filter(db.session, SqlaTable):
has_live = db.session.query(
db.session.query(SqlaTable.id)
.filter(
SqlaTable.database_id == self._model_id,
SqlaTable.deleted_at.is_(None),
)
.exists()
).scalar()
has_any = db.session.query(
db.session.query(SqlaTable.id)
.filter(SqlaTable.database_id == self._model_id)
.exists()
).scalar()
# Both cases block the delete (a soft-deleted dataset still FK-references
# the database), but the message differs: with only hidden rows left the
# operator's dataset list looks empty, so say so explicitly.
if has_live:
raise DatabaseDeleteDatasetsExistFailedError()
if has_any:
raise DatabaseDeleteSoftDeletedDatasetsExistFailedError()
View on GitHub (pinned to f4587218dd)
Solutions
- List the attached datasets (GET /api/v1/dataset/?q=(database_id:<id>)) and delete them (DELETE /api/v1/dataset/<pk>) or migrate them to another database.
- If the data is moving, duplicate datasets against the new database first, then delete the old ones.
- Retry the database delete only after the live dataset count is zero.
Defensive patterns
Strategy: validation
Validate before calling
from superset.models.sql_lab import Query # placeholder
from superset.connectors.sqla.models import SqlaTable
from superset import db
def live_dataset_count(database_id: int) -> int:
return (
db.session.query(SqlaTable.id)
.filter(SqlaTable.database_id == database_id)
.count()
) # non-zero blocks the delete Try / catch
from superset.commands.database.exceptions import DatabaseDeleteDatasetsExistFailedError
try:
DeleteDatabaseCommand(model_id).run()
except DatabaseDeleteDatasetsExistFailedError:
list_and_offer_migration(database_id) # show live datasets, delete or re-point Prevention
- Before deleting a database, list its datasets: GET /api/v1/dataset/?q=(database_id:<id>).
- Migrate or delete all live datasets first; the count is checked with soft-delete visibility bypassed.
When it happens
Trigger: DELETE /api/v1/database/<id> while any dataset in the UI (Datasets list) still points at this database.
Common situations: Decommissioning a database without first migrating or deleting its datasets; datasets created implicitly by CSV uploads; forgetting virtual/saved datasets.
Related errors
- Cannot delete a database whose only remaining datasets are s
- There are associated alerts or reports: %(report_names)s
- There are associated alerts or reports: %(report_names)s
- There are associated alerts or reports: %(report_names)s
- Database not found.
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/09d855b9f7824e38.
Report an issue: GitHub.