diff --git a/superset/reports/commands/alert.py b/superset/reports/commands/alert.py index 600f849224f68..301550f1f94f1 100644 --- a/superset/reports/commands/alert.py +++ b/superset/reports/commands/alert.py @@ -52,7 +52,7 @@ def run(self) -> bool: if self._is_validator_not_null: self._report_schedule.last_value_row_json = str(self._result) - return self._result is not None + return self._result not in (0, None, np.nan) self._report_schedule.last_value = self._result try: operator = json.loads(self._report_schedule.validator_config_json)["op"] @@ -90,7 +90,8 @@ def _validate_result(rows: np.recarray) -> None: def _validate_operator(self, rows: np.recarray) -> None: self._validate_result(rows) - if rows[0][1] is None: + if rows[0][1] in (0, None, np.nan): + self._result = 0.0 return try: # Check if it's float or if we can convert it diff --git a/tests/reports/commands_tests.py b/tests/reports/commands_tests.py index e7516640ed406..e25b6ecef7922 100644 --- a/tests/reports/commands_tests.py +++ b/tests/reports/commands_tests.py @@ -319,7 +319,17 @@ def create_alert_email_chart(request): @pytest.yield_fixture( - params=["alert1", "alert2", "alert3", "alert4", "alert5", "alert6", "alert7"] + params=[ + "alert1", + "alert2", + "alert3", + "alert4", + "alert5", + "alert6", + "alert7", + "alert8", + "alert9", + ] ) def create_no_alert_email_chart(request): param_config = { @@ -358,6 +368,16 @@ def create_no_alert_email_chart(request): "validator_type": ReportScheduleValidatorType.OPERATOR, "validator_config_json": '{"op": ">", "threshold": 0}', }, + "alert8": { + "sql": "SELECT Null as metric", + "validator_type": ReportScheduleValidatorType.NOT_NULL, + "validator_config_json": "{}", + }, + "alert9": { + "sql": "SELECT Null as metric", + "validator_type": ReportScheduleValidatorType.OPERATOR, + "validator_config_json": '{"op": ">", "threshold": 0}', + }, } with app.app_context(): chart = db.session.query(Slice).first()