apache/superset · error · SupersetDMLNotAllowedException
DML_NOT_ALLOWED_ERROR
DML_NOT_ALLOWED_ERROR
Error message
This database does not allow for DDL/DML, but the query mutates data. Please contact your administrator for more assistance.
What it means
Raised in EstimateQueryCostCommand preprocessing (superset/commands/sql_lab/estimate.py:150) as SupersetDMLNotAllowedException when parsed_script.has_mutation() is true and the database record has allow_dml = false. Estimation deliberately runs the same DML guard as execution: even though estimating a mutation does not execute it, the gate blocks the request. SupersetErrorType.DML_NOT_ALLOWED_ERROR.
Source
Thrown at superset/commands/sql_lab/estimate.py:150
resolved_schema = self._database.resolve_query_default_schema(
self._sql, self._schema, catalog, self._template_params
)
# An explicit schema still wins for matching/RLS targeting; otherwise
# fall back to the runtime-resolved default.
effective_schema = self._schema or resolved_schema or ""
if disallowed_tables:
# Honors schema-qualified denylist entries (e.g.
# ``information_schema.tables``) and reports only the tables
# actually referenced by the query.
found_tables = parsed_script.get_disallowed_tables(
disallowed_tables, effective_schema
)
if found_tables:
raise SupersetDisallowedSQLTableException(found_tables)
if parsed_script.has_mutation() and not self._database.allow_dml:
raise SupersetDMLNotAllowedException()
if rls_enabled:
for statement in parsed_script.statements:
apply_rls(self._database, catalog, effective_schema, statement)
return parsed_script.format()
return sql
def run(
self,
) -> list[dict[str, Any]]:
self.validate()
sql = self._sql
if self._template_params:
# Access is already checked in validate() before any rendering.
template_processor = get_template_processor(self._database)
try:View on GitHub (pinned to f4587218dd)
Solutions
- Only estimate SELECT queries on this database, or enable 'Allow DML' in the database settings if mutation is intended (operator decision)
- Move DML statements to a database connection where allow_dml is true
- Check GET /api/v1/database/{id} allow_dml field before offering the estimate action in tooling
Defensive patterns
Strategy: validation
Validate before calling
db = DatabaseDAO.find_by_id(database_id)
if query_mutates(sql) and not db.allow_dml:
raise ValueError("this database disallows DDL/DML; estimate only SELECTs") Try / catch
try:
EstimateQueryCostCommand(params).run()
except SupersetDMLNotAllowedException:
# route the mutation to a DML-enabled database or drop the estimate request Prevention
- Check the database's allow_dml flag before offering cost estimation for DML
- The gate applies to estimation too, by design — do not try to bypass it
When it happens
Trigger: Submitting INSERT/UPDATE/DELETE/CREATE/ALTER/TRUNCATE (or other mutating statements sqlscriptbox detects) for cost estimation on a database whose settings have 'Allow DML' unchecked.
Common situations: Users trying to preview the cost of a data-change script on a read-only connection; admins disabling DML on production databases and users not realizing the estimate path enforces the same policy.
Related errors
- SYNTAX_ERROR
- SQLLAB_TIMEOUT_ERROR
- security_error
- Cannot convert node type: ${node.type}
- Please provide a JWT secret at least 32 bytes long
AI-assisted analysis of apache/superset@f4587218dd (2026-08-14).
Data as JSON: /api/errors/65f0a1b9a768796d.
Report an issue: GitHub.