This is an automated email from the ASF dual-hosted git repository.
eladkal pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 201a9c5af96 Add `accept_none` to `SQLTableCheckOperator` (#63210)
201a9c5af96 is described below
commit 201a9c5af968867958cc66719334c1cfd68380ee
Author: Jake McGrath <[email protected]>
AuthorDate: Mon Apr 13 15:09:11 2026 -0400
Add `accept_none` to `SQLTableCheckOperator` (#63210)
* issue-30082: Adding accept_none to SQLTableCheckOperator
* Update
providers/common/sql/src/airflow/providers/common/sql/operators/sql.py
Co-authored-by: Elad Kalif <[email protected]>
* fix static checks
---------
Co-authored-by: Elad Kalif <[email protected]>
---
.../sql/src/airflow/providers/common/sql/operators/sql.py | 13 +++++++++++++
.../sql/tests/unit/common/sql/operators/test_sql.py | 15 +++++++++++++++
2 files changed, 28 insertions(+)
diff --git
a/providers/common/sql/src/airflow/providers/common/sql/operators/sql.py
b/providers/common/sql/src/airflow/providers/common/sql/operators/sql.py
index 7d8e65df73b..285b4657be6 100644
--- a/providers/common/sql/src/airflow/providers/common/sql/operators/sql.py
+++ b/providers/common/sql/src/airflow/providers/common/sql/operators/sql.py
@@ -714,6 +714,7 @@ class SQLTableCheckOperator(BaseSQLOperator):
:param conn_id: the connection ID used to connect to the database
:param database: name of database which overwrite the defined one in
connection
+ :param accept_none: If True, an empty table (row count=0) will not trigger
a failure.
.. seealso::
For more information on how to use this operator, take a look at the
guide:
@@ -738,6 +739,7 @@ class SQLTableCheckOperator(BaseSQLOperator):
partition_clause: str | None = None,
conn_id: str | None = None,
database: str | None = None,
+ accept_none: bool = False,
**kwargs,
):
super().__init__(conn_id=conn_id, database=database, **kwargs)
@@ -745,6 +747,7 @@ class SQLTableCheckOperator(BaseSQLOperator):
self.table = table
self.checks = checks
self.partition_clause = _initialize_partition_clause(partition_clause)
+ self.accept_none = accept_none
self.sql = f"SELECT check_name, check_result FROM
({self._generate_sql_query()}) AS check_table"
def execute(self, context: Context):
@@ -752,6 +755,16 @@ class SQLTableCheckOperator(BaseSQLOperator):
records = hook.get_records(self.sql)
if not records:
+ # accept_none prevents an error from being thrown if there are no
records in the table
+ if self.accept_none:
+ self.log.warning(
+ "No records found for table: %s, but accept_none=True, "
+ "therefore, no tests are being marked as failed.",
+ self.table,
+ )
+ return
+
+ # Otherwise, we'll raise an exception
self._raise_exception(f"The following query returned zero rows:
{self.sql}")
self.log.info("Record:\n%s", records)
diff --git a/providers/common/sql/tests/unit/common/sql/operators/test_sql.py
b/providers/common/sql/tests/unit/common/sql/operators/test_sql.py
index abe38efbdb9..08becbc12e1 100644
--- a/providers/common/sql/tests/unit/common/sql/operators/test_sql.py
+++ b/providers/common/sql/tests/unit/common/sql/operators/test_sql.py
@@ -605,6 +605,21 @@ class TestTableCheckOperator:
finally:
hook.run(["DROP TABLE employees"])
+ def test_sql_check_accept_none_true(self, monkeypatch):
+ """Validate that empty table does not fail when accept_none=True."""
+ records = []
+ operator = self._construct_operator(monkeypatch, self.checks, records)
+ operator.accept_none = True
+ operator.execute(context=MagicMock())
+
+ def test_sql_check_accept_none_false(self, monkeypatch):
+ """Validate that empty table throws an exception when
accept_none=False."""
+ records = []
+ operator = self._construct_operator(monkeypatch, self.checks, records)
+ operator.accept_none = False # This is default, technically
+ with pytest.raises(AirflowException):
+ operator.execute(context=MagicMock())
+
def test_pass_all_checks_check(self, monkeypatch):
records = [("row_count_check", 1), ("column_sum_check", "y")]
operator = self._construct_operator(monkeypatch, self.checks, records)