mirror of https://github.com/apache/superset.git
fix(alerts): void query with numeric comparison (#13090)
* fix(alerts): void query with numeric comparison * remove config changes * fix tests * better logic * fix logic * fix logic * Improve test readability
This commit is contained in:
parent
613945a200
commit
2e6ea76631
|
@ -47,15 +47,16 @@ class AlertCommand(BaseCommand):
|
|||
def run(self) -> bool:
|
||||
self.validate()
|
||||
|
||||
if self._report_schedule.validator_type == ReportScheduleValidatorType.NOT_NULL:
|
||||
if self._is_validator_not_null:
|
||||
self._report_schedule.last_value_row_json = str(self._result)
|
||||
return self._result not in (0, None, np.nan)
|
||||
return self._result is not None
|
||||
self._report_schedule.last_value = self._result
|
||||
try:
|
||||
operator = json.loads(self._report_schedule.validator_config_json)["op"]
|
||||
threshold = json.loads(self._report_schedule.validator_config_json)[
|
||||
"threshold"
|
||||
]
|
||||
|
||||
return OPERATOR_FUNCTIONS[operator](self._result, threshold)
|
||||
except (KeyError, json.JSONDecodeError):
|
||||
raise AlertValidatorConfigError()
|
||||
|
@ -95,6 +96,18 @@ class AlertCommand(BaseCommand):
|
|||
except (AssertionError, TypeError, ValueError):
|
||||
raise AlertQueryInvalidTypeError()
|
||||
|
||||
@property
|
||||
def _is_validator_not_null(self) -> bool:
|
||||
return (
|
||||
self._report_schedule.validator_type == ReportScheduleValidatorType.NOT_NULL
|
||||
)
|
||||
|
||||
@property
|
||||
def _is_validator_operator(self) -> bool:
|
||||
return (
|
||||
self._report_schedule.validator_type == ReportScheduleValidatorType.OPERATOR
|
||||
)
|
||||
|
||||
def validate(self) -> None:
|
||||
"""
|
||||
Validate the query result as a Pandas DataFrame
|
||||
|
@ -108,10 +121,14 @@ class AlertCommand(BaseCommand):
|
|||
except Exception as ex:
|
||||
raise AlertQueryError(message=str(ex))
|
||||
|
||||
if df.empty:
|
||||
if df.empty and self._is_validator_not_null:
|
||||
self._result = None
|
||||
return
|
||||
if df.empty and self._is_validator_operator:
|
||||
self._result = 0.0
|
||||
return
|
||||
rows = df.to_records()
|
||||
if self._report_schedule.validator_type == ReportScheduleValidatorType.NOT_NULL:
|
||||
if self._is_validator_not_null:
|
||||
self._validate_not_null(rows)
|
||||
return
|
||||
self._validate_operator(rows)
|
||||
|
|
|
@ -308,7 +308,7 @@ def create_test_table_context(database: Database):
|
|||
|
||||
|
||||
@pytest.yield_fixture(
|
||||
params=["alert1", "alert2", "alert3", "alert4", "alert5", "alert6"]
|
||||
params=["alert1", "alert2", "alert3", "alert4", "alert5", "alert6", "alert7"]
|
||||
)
|
||||
def create_no_alert_email_chart(request):
|
||||
param_config = {
|
||||
|
@ -338,10 +338,15 @@ def create_no_alert_email_chart(request):
|
|||
"validator_config_json": '{"op": "!=", "threshold": 10}',
|
||||
},
|
||||
"alert6": {
|
||||
"sql": "SELECT first from test_table where first=0",
|
||||
"sql": "SELECT first from test_table where 1=0",
|
||||
"validator_type": ReportScheduleValidatorType.NOT_NULL,
|
||||
"validator_config_json": "{}",
|
||||
},
|
||||
"alert7": {
|
||||
"sql": "SELECT first from test_table where 1=0",
|
||||
"validator_type": ReportScheduleValidatorType.OPERATOR,
|
||||
"validator_config_json": '{"op": ">", "threshold": 0}',
|
||||
},
|
||||
}
|
||||
with app.app_context():
|
||||
chart = db.session.query(Slice).first()
|
||||
|
|
Loading…
Reference in New Issue