16
16
# under the License.
17
17
from __future__ import annotations
18
18
19
+ from operator import itemgetter
19
20
from typing import TYPE_CHECKING , Any , Callable , Mapping , Sequence
20
21
21
22
from airflow .exceptions import AirflowException
@@ -46,10 +47,12 @@ class SqlSensor(BaseSensorOperator):
46
47
:param sql: The SQL to run. To pass, it needs to return at least one cell
47
48
that contains a non-zero / empty string value.
48
49
:param parameters: The parameters to render the SQL query with (optional).
49
- :param success: Success criteria for the sensor is a Callable that takes the first_cell's value
50
- as the only argument, and returns a boolean (optional).
51
- :param failure: Failure criteria for the sensor is a Callable that takes the first_cell's value
52
- as the only argument and returns a boolean (optional).
50
+ :param success: Success criteria for the sensor is a Callable that takes the output
51
+ of selector as the only argument, and returns a boolean (optional).
52
+ :param failure: Failure criteria for the sensor is a Callable that takes the output
53
+ of selector as the only argument and returns a boolean (optional).
54
+ :param selector: Function which takes the resulting row and transforms it before
55
+ it is passed to success or failure (optional). Takes the first cell by default.
53
56
:param fail_on_empty: Explicitly fail on no rows returned.
54
57
:param hook_params: Extra config params to be passed to the underlying hook.
55
58
Should match the desired hook constructor params.
@@ -67,6 +70,7 @@ def __init__(
67
70
parameters : Mapping [str , Any ] | None = None ,
68
71
success : Callable [[Any ], bool ] | None = None ,
69
72
failure : Callable [[Any ], bool ] | None = None ,
73
+ selector : Callable [[tuple [Any ]], Any ] | None = itemgetter (0 ),
70
74
fail_on_empty : bool = False ,
71
75
hook_params : Mapping [str , Any ] | None = None ,
72
76
** kwargs ,
@@ -76,6 +80,7 @@ def __init__(
76
80
self .parameters = parameters
77
81
self .success = success
78
82
self .failure = failure
83
+ self .selector = selector
79
84
self .fail_on_empty = fail_on_empty
80
85
self .hook_params = hook_params
81
86
super ().__init__ (** kwargs )
@@ -102,20 +107,20 @@ def poke(self, context: Context) -> bool:
102
107
else :
103
108
return False
104
109
105
- first_cell = records [0 ][ 0 ]
110
+ condition = self . selector ( records [0 ])
106
111
if self .failure is not None :
107
112
if callable (self .failure ):
108
- if self .failure (first_cell ):
109
- message = f"Failure criteria met. self.failure({ first_cell } ) returned True"
113
+ if self .failure (condition ):
114
+ message = f"Failure criteria met. self.failure({ condition } ) returned True"
110
115
raise AirflowException (message )
111
116
else :
112
117
message = f"self.failure is present, but not callable -> { self .failure } "
113
118
raise AirflowException (message )
114
119
115
120
if self .success is not None :
116
121
if callable (self .success ):
117
- return self .success (first_cell )
122
+ return self .success (condition )
118
123
else :
119
124
message = f"self.success is present, but not callable -> { self .success } "
120
125
raise AirflowException (message )
121
- return bool (first_cell )
126
+ return bool (condition )
0 commit comments