apache-airflow-providers-common-sql 1.30.0rc2__py3-none-any.whl → 1.30.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- airflow/providers/common/sql/__init__.py +1 -1
- airflow/providers/common/sql/hooks/sql.py +4 -8
- airflow/providers/common/sql/operators/generic_transfer.py +1 -2
- airflow/providers/common/sql/operators/generic_transfer.pyi +1 -1
- airflow/providers/common/sql/operators/sql.py +123 -91
- airflow/providers/common/sql/sensors/sql.py +1 -2
- airflow/providers/common/sql/sensors/sql.pyi +1 -1
- airflow/providers/common/sql/triggers/sql.py +1 -2
- {apache_airflow_providers_common_sql-1.30.0rc2.dist-info → apache_airflow_providers_common_sql-1.30.2.dist-info}/METADATA +9 -9
- {apache_airflow_providers_common_sql-1.30.0rc2.dist-info → apache_airflow_providers_common_sql-1.30.2.dist-info}/RECORD +14 -14
- {apache_airflow_providers_common_sql-1.30.0rc2.dist-info → apache_airflow_providers_common_sql-1.30.2.dist-info}/WHEEL +0 -0
- {apache_airflow_providers_common_sql-1.30.0rc2.dist-info → apache_airflow_providers_common_sql-1.30.2.dist-info}/entry_points.txt +0 -0
- {apache_airflow_providers_common_sql-1.30.0rc2.dist-info → apache_airflow_providers_common_sql-1.30.2.dist-info}/licenses/LICENSE +0 -0
- {apache_airflow_providers_common_sql-1.30.0rc2.dist-info → apache_airflow_providers_common_sql-1.30.2.dist-info}/licenses/NOTICE +0 -0
|
@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
|
|
|
29
29
|
|
|
30
30
|
__all__ = ["__version__"]
|
|
31
31
|
|
|
32
|
-
__version__ = "1.30.
|
|
32
|
+
__version__ = "1.30.2"
|
|
33
33
|
|
|
34
34
|
if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
|
|
35
35
|
"2.11.0"
|
|
@@ -34,15 +34,11 @@ from sqlalchemy.engine import make_url
|
|
|
34
34
|
from sqlalchemy.exc import ArgumentError, NoSuchModuleError
|
|
35
35
|
|
|
36
36
|
from airflow.configuration import conf
|
|
37
|
-
from airflow.exceptions import
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
AirflowProviderDeprecationWarning,
|
|
41
|
-
)
|
|
42
|
-
from airflow.providers.common.compat.sdk import BaseHook
|
|
37
|
+
from airflow.exceptions import AirflowOptionalProviderFeatureException, AirflowProviderDeprecationWarning
|
|
38
|
+
from airflow.providers.common.compat.module_loading import import_string
|
|
39
|
+
from airflow.providers.common.compat.sdk import AirflowException, BaseHook
|
|
43
40
|
from airflow.providers.common.sql.dialects.dialect import Dialect
|
|
44
41
|
from airflow.providers.common.sql.hooks import handlers
|
|
45
|
-
from airflow.utils.module_loading import import_string
|
|
46
42
|
|
|
47
43
|
if TYPE_CHECKING:
|
|
48
44
|
from pandas import DataFrame as PandasDataFrame
|
|
@@ -337,7 +333,7 @@ class DbApiHook(BaseHook):
|
|
|
337
333
|
|
|
338
334
|
@cached_property
|
|
339
335
|
def dialect(self) -> Dialect:
|
|
340
|
-
from airflow.
|
|
336
|
+
from airflow.providers.common.compat.module_loading import import_string
|
|
341
337
|
|
|
342
338
|
dialect_info = self._dialects.get(self.dialect_name)
|
|
343
339
|
|
|
@@ -21,8 +21,7 @@ from collections.abc import Sequence
|
|
|
21
21
|
from functools import cached_property
|
|
22
22
|
from typing import TYPE_CHECKING, Any
|
|
23
23
|
|
|
24
|
-
from airflow.
|
|
25
|
-
from airflow.providers.common.compat.sdk import BaseHook, BaseOperator
|
|
24
|
+
from airflow.providers.common.compat.sdk import AirflowException, BaseHook, BaseOperator
|
|
26
25
|
from airflow.providers.common.sql.hooks.sql import DbApiHook
|
|
27
26
|
from airflow.providers.common.sql.triggers.sql import SQLExecuteQueryTrigger
|
|
28
27
|
|
|
@@ -38,7 +38,7 @@ from _typeshed import Incomplete as Incomplete
|
|
|
38
38
|
|
|
39
39
|
from airflow.models import BaseOperator
|
|
40
40
|
from airflow.providers.common.sql.hooks.sql import DbApiHook as DbApiHook
|
|
41
|
-
from airflow.
|
|
41
|
+
from airflow.sdk import Context
|
|
42
42
|
|
|
43
43
|
class GenericTransfer(BaseOperator):
|
|
44
44
|
template_fields: Sequence[str]
|
|
@@ -24,9 +24,9 @@ from functools import cached_property
|
|
|
24
24
|
from typing import TYPE_CHECKING, Any, ClassVar, NoReturn, SupportsAbs
|
|
25
25
|
|
|
26
26
|
from airflow import XComArg
|
|
27
|
-
from airflow.exceptions import AirflowException
|
|
28
27
|
from airflow.models import SkipMixin
|
|
29
28
|
from airflow.providers.common.compat.sdk import (
|
|
29
|
+
AirflowException,
|
|
30
30
|
AirflowFailException,
|
|
31
31
|
AirflowSkipException,
|
|
32
32
|
BaseHook,
|
|
@@ -213,6 +213,86 @@ class BaseSQLOperator(BaseOperator):
|
|
|
213
213
|
raise AirflowException(exception_string)
|
|
214
214
|
raise AirflowFailException(exception_string)
|
|
215
215
|
|
|
216
|
+
def get_openlineage_facets_on_start(self) -> OperatorLineage | None:
|
|
217
|
+
"""Generate OpenLineage facets on start for SQL operators."""
|
|
218
|
+
try:
|
|
219
|
+
from airflow.providers.openlineage.extractors import OperatorLineage
|
|
220
|
+
from airflow.providers.openlineage.sqlparser import SQLParser
|
|
221
|
+
except ImportError:
|
|
222
|
+
self.log.debug("OpenLineage could not import required classes. Skipping.")
|
|
223
|
+
return None
|
|
224
|
+
|
|
225
|
+
sql = getattr(self, "sql", None)
|
|
226
|
+
if not sql:
|
|
227
|
+
self.log.debug("OpenLineage could not find 'sql' attribute on `%s`.", type(self).__name__)
|
|
228
|
+
return OperatorLineage()
|
|
229
|
+
|
|
230
|
+
hook = self.get_db_hook()
|
|
231
|
+
try:
|
|
232
|
+
from airflow.providers.openlineage.utils.utils import should_use_external_connection
|
|
233
|
+
|
|
234
|
+
use_external_connection = should_use_external_connection(hook)
|
|
235
|
+
except ImportError:
|
|
236
|
+
# OpenLineage provider release < 1.8.0 - we always use connection
|
|
237
|
+
use_external_connection = True
|
|
238
|
+
|
|
239
|
+
connection = hook.get_connection(getattr(hook, hook.conn_name_attr))
|
|
240
|
+
try:
|
|
241
|
+
database_info = hook.get_openlineage_database_info(connection)
|
|
242
|
+
except AttributeError:
|
|
243
|
+
self.log.debug("%s has no database info provided", hook)
|
|
244
|
+
database_info = None
|
|
245
|
+
|
|
246
|
+
if database_info is None:
|
|
247
|
+
self.log.debug("OpenLineage could not retrieve database information. Skipping.")
|
|
248
|
+
return OperatorLineage()
|
|
249
|
+
|
|
250
|
+
try:
|
|
251
|
+
sql_parser = SQLParser(
|
|
252
|
+
dialect=hook.get_openlineage_database_dialect(connection),
|
|
253
|
+
default_schema=hook.get_openlineage_default_schema(),
|
|
254
|
+
)
|
|
255
|
+
except AttributeError:
|
|
256
|
+
self.log.debug("%s failed to get database dialect", hook)
|
|
257
|
+
return None
|
|
258
|
+
|
|
259
|
+
operator_lineage = sql_parser.generate_openlineage_metadata_from_sql(
|
|
260
|
+
sql=sql,
|
|
261
|
+
hook=hook,
|
|
262
|
+
database_info=database_info,
|
|
263
|
+
database=self.database,
|
|
264
|
+
sqlalchemy_engine=hook.get_sqlalchemy_engine(),
|
|
265
|
+
use_connection=use_external_connection,
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
return operator_lineage
|
|
269
|
+
|
|
270
|
+
def get_openlineage_facets_on_complete(self, task_instance) -> OperatorLineage | None:
|
|
271
|
+
"""Generate OpenLineage facets when task completes."""
|
|
272
|
+
try:
|
|
273
|
+
from airflow.providers.openlineage.extractors import OperatorLineage
|
|
274
|
+
except ImportError:
|
|
275
|
+
self.log.debug("OpenLineage could not import required classes. Skipping.")
|
|
276
|
+
return None
|
|
277
|
+
|
|
278
|
+
operator_lineage = self.get_openlineage_facets_on_start() or OperatorLineage()
|
|
279
|
+
hook = self.get_db_hook()
|
|
280
|
+
try:
|
|
281
|
+
database_specific_lineage = hook.get_openlineage_database_specific_lineage(task_instance)
|
|
282
|
+
except AttributeError:
|
|
283
|
+
self.log.debug("%s has no database specific lineage provided", hook)
|
|
284
|
+
database_specific_lineage = None
|
|
285
|
+
|
|
286
|
+
if database_specific_lineage is None:
|
|
287
|
+
return operator_lineage
|
|
288
|
+
|
|
289
|
+
return OperatorLineage(
|
|
290
|
+
inputs=operator_lineage.inputs + database_specific_lineage.inputs,
|
|
291
|
+
outputs=operator_lineage.outputs + database_specific_lineage.outputs,
|
|
292
|
+
run_facets=merge_dicts(operator_lineage.run_facets, database_specific_lineage.run_facets),
|
|
293
|
+
job_facets=merge_dicts(operator_lineage.job_facets, database_specific_lineage.job_facets),
|
|
294
|
+
)
|
|
295
|
+
|
|
216
296
|
|
|
217
297
|
class SQLExecuteQueryOperator(BaseSQLOperator):
|
|
218
298
|
"""
|
|
@@ -343,76 +423,6 @@ class SQLExecuteQueryOperator(BaseSQLOperator):
|
|
|
343
423
|
if isinstance(self.parameters, str):
|
|
344
424
|
self.parameters = ast.literal_eval(self.parameters)
|
|
345
425
|
|
|
346
|
-
def get_openlineage_facets_on_start(self) -> OperatorLineage | None:
|
|
347
|
-
try:
|
|
348
|
-
from airflow.providers.openlineage.sqlparser import SQLParser
|
|
349
|
-
except ImportError:
|
|
350
|
-
return None
|
|
351
|
-
|
|
352
|
-
hook = self.get_db_hook()
|
|
353
|
-
|
|
354
|
-
try:
|
|
355
|
-
from airflow.providers.openlineage.utils.utils import should_use_external_connection
|
|
356
|
-
|
|
357
|
-
use_external_connection = should_use_external_connection(hook)
|
|
358
|
-
except ImportError:
|
|
359
|
-
# OpenLineage provider release < 1.8.0 - we always use connection
|
|
360
|
-
use_external_connection = True
|
|
361
|
-
|
|
362
|
-
connection = hook.get_connection(getattr(hook, hook.conn_name_attr))
|
|
363
|
-
try:
|
|
364
|
-
database_info = hook.get_openlineage_database_info(connection)
|
|
365
|
-
except AttributeError:
|
|
366
|
-
self.log.debug("%s has no database info provided", hook)
|
|
367
|
-
database_info = None
|
|
368
|
-
|
|
369
|
-
if database_info is None:
|
|
370
|
-
return None
|
|
371
|
-
|
|
372
|
-
try:
|
|
373
|
-
sql_parser = SQLParser(
|
|
374
|
-
dialect=hook.get_openlineage_database_dialect(connection),
|
|
375
|
-
default_schema=hook.get_openlineage_default_schema(),
|
|
376
|
-
)
|
|
377
|
-
except AttributeError:
|
|
378
|
-
self.log.debug("%s failed to get database dialect", hook)
|
|
379
|
-
return None
|
|
380
|
-
|
|
381
|
-
operator_lineage = sql_parser.generate_openlineage_metadata_from_sql(
|
|
382
|
-
sql=self.sql,
|
|
383
|
-
hook=hook,
|
|
384
|
-
database_info=database_info,
|
|
385
|
-
database=self.database,
|
|
386
|
-
sqlalchemy_engine=hook.get_sqlalchemy_engine(),
|
|
387
|
-
use_connection=use_external_connection,
|
|
388
|
-
)
|
|
389
|
-
|
|
390
|
-
return operator_lineage
|
|
391
|
-
|
|
392
|
-
def get_openlineage_facets_on_complete(self, task_instance) -> OperatorLineage | None:
|
|
393
|
-
try:
|
|
394
|
-
from airflow.providers.openlineage.extractors import OperatorLineage
|
|
395
|
-
except ImportError:
|
|
396
|
-
return None
|
|
397
|
-
|
|
398
|
-
operator_lineage = self.get_openlineage_facets_on_start() or OperatorLineage()
|
|
399
|
-
|
|
400
|
-
hook = self.get_db_hook()
|
|
401
|
-
try:
|
|
402
|
-
database_specific_lineage = hook.get_openlineage_database_specific_lineage(task_instance)
|
|
403
|
-
except AttributeError:
|
|
404
|
-
database_specific_lineage = None
|
|
405
|
-
|
|
406
|
-
if database_specific_lineage is None:
|
|
407
|
-
return operator_lineage
|
|
408
|
-
|
|
409
|
-
return OperatorLineage(
|
|
410
|
-
inputs=operator_lineage.inputs + database_specific_lineage.inputs,
|
|
411
|
-
outputs=operator_lineage.outputs + database_specific_lineage.outputs,
|
|
412
|
-
run_facets=merge_dicts(operator_lineage.run_facets, database_specific_lineage.run_facets),
|
|
413
|
-
job_facets=merge_dicts(operator_lineage.job_facets, database_specific_lineage.job_facets),
|
|
414
|
-
)
|
|
415
|
-
|
|
416
426
|
|
|
417
427
|
class SQLColumnCheckOperator(BaseSQLOperator):
|
|
418
428
|
"""
|
|
@@ -852,6 +862,9 @@ class SQLValueCheckOperator(BaseSQLOperator):
|
|
|
852
862
|
:param sql: the sql to be executed. (templated)
|
|
853
863
|
:param conn_id: the connection ID used to connect to the database.
|
|
854
864
|
:param database: name of database which overwrite the defined one in connection
|
|
865
|
+
:param pass_value: the value to check against
|
|
866
|
+
:param tolerance: (optional) the tolerance allowed to pass records within for
|
|
867
|
+
numeric queries
|
|
855
868
|
"""
|
|
856
869
|
|
|
857
870
|
__mapper_args__ = {"polymorphic_identity": "SQLValueCheckOperator"}
|
|
@@ -999,8 +1012,13 @@ class SQLIntervalCheckOperator(BaseSQLOperator):
|
|
|
999
1012
|
|
|
1000
1013
|
self.sql1 = f"{sqlt}'{{{{ ds }}}}'"
|
|
1001
1014
|
self.sql2 = f"{sqlt}'{{{{ macros.ds_add(ds, {self.days_back}) }}}}'"
|
|
1015
|
+
# Save all queries as `sql` attr - similar to other sql operators (to be used by listeners).
|
|
1016
|
+
self.sql: list[str] = [self.sql1, self.sql2]
|
|
1002
1017
|
|
|
1003
1018
|
def execute(self, context: Context):
|
|
1019
|
+
# Re-set with templated queries
|
|
1020
|
+
self.sql = [self.sql1, self.sql2]
|
|
1021
|
+
|
|
1004
1022
|
hook = self.get_db_hook()
|
|
1005
1023
|
self.log.info("Using ratio formula: %s", self.ratio_formula)
|
|
1006
1024
|
self.log.info("Executing SQL check: %s", self.sql2)
|
|
@@ -1017,25 +1035,36 @@ class SQLIntervalCheckOperator(BaseSQLOperator):
|
|
|
1017
1035
|
reference = dict(zip(self.metrics_sorted, row2))
|
|
1018
1036
|
|
|
1019
1037
|
ratios: dict[str, int | None] = {}
|
|
1020
|
-
|
|
1038
|
+
# Save all details about all tests to be used in error message if needed
|
|
1039
|
+
all_tests_results: dict[str, dict[str, Any]] = {}
|
|
1021
1040
|
|
|
1022
1041
|
for metric in self.metrics_sorted:
|
|
1023
1042
|
cur = current[metric]
|
|
1024
1043
|
ref = reference[metric]
|
|
1025
1044
|
threshold = self.metrics_thresholds[metric]
|
|
1045
|
+
single_metric_results = {
|
|
1046
|
+
"metric": metric,
|
|
1047
|
+
"current_metric": cur,
|
|
1048
|
+
"past_metric": ref,
|
|
1049
|
+
"threshold": threshold,
|
|
1050
|
+
"ignore_zero": self.ignore_zero,
|
|
1051
|
+
}
|
|
1026
1052
|
if cur == 0 or ref == 0:
|
|
1027
1053
|
ratios[metric] = None
|
|
1028
|
-
|
|
1054
|
+
single_metric_results["ratio"] = None
|
|
1055
|
+
single_metric_results["success"] = self.ignore_zero
|
|
1029
1056
|
else:
|
|
1030
1057
|
ratio_metric = self.ratio_formulas[self.ratio_formula](current[metric], reference[metric])
|
|
1031
1058
|
ratios[metric] = ratio_metric
|
|
1059
|
+
single_metric_results["ratio"] = ratio_metric
|
|
1032
1060
|
if ratio_metric is not None:
|
|
1033
|
-
|
|
1061
|
+
single_metric_results["success"] = ratio_metric < threshold
|
|
1034
1062
|
else:
|
|
1035
|
-
|
|
1063
|
+
single_metric_results["success"] = self.ignore_zero
|
|
1036
1064
|
|
|
1065
|
+
all_tests_results[metric] = single_metric_results
|
|
1037
1066
|
self.log.info(
|
|
1038
|
-
|
|
1067
|
+
"Current metric for %s: %s\nPast metric for %s: %s\nRatio for %s: %s\nThreshold: %s\n",
|
|
1039
1068
|
metric,
|
|
1040
1069
|
cur,
|
|
1041
1070
|
metric,
|
|
@@ -1045,21 +1074,24 @@ class SQLIntervalCheckOperator(BaseSQLOperator):
|
|
|
1045
1074
|
threshold,
|
|
1046
1075
|
)
|
|
1047
1076
|
|
|
1048
|
-
|
|
1049
|
-
|
|
1077
|
+
failed_tests = [single for single in all_tests_results.values() if not single["success"]]
|
|
1078
|
+
if failed_tests:
|
|
1050
1079
|
self.log.warning(
|
|
1051
1080
|
"The following %s tests out of %s failed:",
|
|
1052
1081
|
len(failed_tests),
|
|
1053
1082
|
len(self.metrics_sorted),
|
|
1054
1083
|
)
|
|
1055
|
-
for
|
|
1084
|
+
for single_filed_test in failed_tests:
|
|
1056
1085
|
self.log.warning(
|
|
1057
1086
|
"'%s' check failed. %s is above %s",
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1087
|
+
single_filed_test["metric"],
|
|
1088
|
+
single_filed_test["ratio"],
|
|
1089
|
+
single_filed_test["threshold"],
|
|
1061
1090
|
)
|
|
1062
|
-
|
|
1091
|
+
failed_test_details = "; ".join(
|
|
1092
|
+
f"{t['metric']}: {t}" for t in sorted(failed_tests, key=lambda x: x["metric"])
|
|
1093
|
+
)
|
|
1094
|
+
self._raise_exception(f"The following tests have failed:\n {failed_test_details}")
|
|
1063
1095
|
|
|
1064
1096
|
self.log.info("All tests have passed")
|
|
1065
1097
|
|
|
@@ -1206,6 +1238,8 @@ class BranchSQLOperator(BaseSQLOperator, SkipMixin):
|
|
|
1206
1238
|
self.parameters = parameters
|
|
1207
1239
|
self.follow_task_ids_if_true = follow_task_ids_if_true
|
|
1208
1240
|
self.follow_task_ids_if_false = follow_task_ids_if_false
|
|
1241
|
+
# Chosen branch, after evaluating condition, set during execution, to be used by listeners
|
|
1242
|
+
self.follow_branch: list[str] | None = None
|
|
1209
1243
|
|
|
1210
1244
|
def execute(self, context: Context):
|
|
1211
1245
|
self.log.info(
|
|
@@ -1232,32 +1266,30 @@ class BranchSQLOperator(BaseSQLOperator, SkipMixin):
|
|
|
1232
1266
|
|
|
1233
1267
|
self.log.info("Query returns %s, type '%s'", query_result, type(query_result))
|
|
1234
1268
|
|
|
1235
|
-
follow_branch = None
|
|
1236
1269
|
try:
|
|
1237
1270
|
if isinstance(query_result, bool):
|
|
1238
1271
|
if query_result:
|
|
1239
|
-
follow_branch = self.follow_task_ids_if_true
|
|
1272
|
+
self.follow_branch = self.follow_task_ids_if_true
|
|
1240
1273
|
elif isinstance(query_result, str):
|
|
1241
1274
|
# return result is not Boolean, try to convert from String to Boolean
|
|
1242
1275
|
if _parse_boolean(query_result):
|
|
1243
|
-
follow_branch = self.follow_task_ids_if_true
|
|
1276
|
+
self.follow_branch = self.follow_task_ids_if_true
|
|
1244
1277
|
elif isinstance(query_result, int):
|
|
1245
1278
|
if bool(query_result):
|
|
1246
|
-
follow_branch = self.follow_task_ids_if_true
|
|
1279
|
+
self.follow_branch = self.follow_task_ids_if_true
|
|
1247
1280
|
else:
|
|
1248
1281
|
raise AirflowException(
|
|
1249
1282
|
f"Unexpected query return result '{query_result}' type '{type(query_result)}'"
|
|
1250
1283
|
)
|
|
1251
1284
|
|
|
1252
|
-
if follow_branch is None:
|
|
1253
|
-
follow_branch = self.follow_task_ids_if_false
|
|
1285
|
+
if self.follow_branch is None:
|
|
1286
|
+
self.follow_branch = self.follow_task_ids_if_false
|
|
1254
1287
|
except ValueError:
|
|
1255
1288
|
raise AirflowException(
|
|
1256
1289
|
f"Unexpected query return result '{query_result}' type '{type(query_result)}'"
|
|
1257
1290
|
)
|
|
1258
1291
|
|
|
1259
|
-
|
|
1260
|
-
self.skip_all_except(context["ti"], follow_branch)
|
|
1292
|
+
self.skip_all_except(context["ti"], self.follow_branch)
|
|
1261
1293
|
|
|
1262
1294
|
|
|
1263
1295
|
class SQLInsertRowsOperator(BaseSQLOperator):
|
|
@@ -20,8 +20,7 @@ from collections.abc import Callable, Mapping, Sequence
|
|
|
20
20
|
from operator import itemgetter
|
|
21
21
|
from typing import TYPE_CHECKING, Any
|
|
22
22
|
|
|
23
|
-
from airflow.
|
|
24
|
-
from airflow.providers.common.compat.sdk import BaseHook, BaseSensorOperator
|
|
23
|
+
from airflow.providers.common.compat.sdk import AirflowException, BaseHook, BaseSensorOperator
|
|
25
24
|
from airflow.providers.common.sql.hooks.sql import DbApiHook
|
|
26
25
|
|
|
27
26
|
if TYPE_CHECKING:
|
|
@@ -38,7 +38,7 @@ from typing import Any
|
|
|
38
38
|
from _typeshed import Incomplete as Incomplete
|
|
39
39
|
|
|
40
40
|
from airflow.providers.common.compat.sdk import BaseSensorOperator
|
|
41
|
-
from airflow.
|
|
41
|
+
from airflow.sdk import Context
|
|
42
42
|
|
|
43
43
|
class SqlSensor(BaseSensorOperator):
|
|
44
44
|
template_fields: Sequence[str]
|
|
@@ -19,8 +19,7 @@ from __future__ import annotations
|
|
|
19
19
|
|
|
20
20
|
from typing import TYPE_CHECKING
|
|
21
21
|
|
|
22
|
-
from airflow.
|
|
23
|
-
from airflow.providers.common.compat.sdk import BaseHook
|
|
22
|
+
from airflow.providers.common.compat.sdk import AirflowException, BaseHook
|
|
24
23
|
from airflow.providers.common.sql.hooks.sql import DbApiHook
|
|
25
24
|
from airflow.triggers.base import BaseTrigger, TriggerEvent
|
|
26
25
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apache-airflow-providers-common-sql
|
|
3
|
-
Version: 1.30.
|
|
3
|
+
Version: 1.30.2
|
|
4
4
|
Summary: Provider package apache-airflow-providers-common-sql for Apache Airflow
|
|
5
5
|
Keywords: airflow-provider,common.sql,airflow,integration
|
|
6
6
|
Author-email: Apache Software Foundation <dev@airflow.apache.org>
|
|
@@ -22,8 +22,8 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
22
22
|
Classifier: Topic :: System :: Monitoring
|
|
23
23
|
License-File: LICENSE
|
|
24
24
|
License-File: NOTICE
|
|
25
|
-
Requires-Dist: apache-airflow>=2.11.
|
|
26
|
-
Requires-Dist: apache-airflow-providers-common-compat>=1.
|
|
25
|
+
Requires-Dist: apache-airflow>=2.11.0
|
|
26
|
+
Requires-Dist: apache-airflow-providers-common-compat>=1.11.0
|
|
27
27
|
Requires-Dist: sqlparse>=0.5.1
|
|
28
28
|
Requires-Dist: more-itertools>=9.0.0
|
|
29
29
|
Requires-Dist: methodtools>=0.4.7
|
|
@@ -32,8 +32,8 @@ Requires-Dist: pandas[sql-other]>=2.1.2 ; extra == "pandas" and ( python_version
|
|
|
32
32
|
Requires-Dist: pandas>=2.2.3 ; extra == "pandas" and ( python_version >="3.13")
|
|
33
33
|
Requires-Dist: polars>=1.26.0 ; extra == "polars"
|
|
34
34
|
Project-URL: Bug Tracker, https://github.com/apache/airflow/issues
|
|
35
|
-
Project-URL: Changelog, https://airflow.
|
|
36
|
-
Project-URL: Documentation, https://airflow.
|
|
35
|
+
Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-common-sql/1.30.2/changelog.html
|
|
36
|
+
Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-common-sql/1.30.2
|
|
37
37
|
Project-URL: Mastodon, https://fosstodon.org/@airflow
|
|
38
38
|
Project-URL: Slack Chat, https://s.apache.org/airflow-slack
|
|
39
39
|
Project-URL: Source Code, https://github.com/apache/airflow
|
|
@@ -67,7 +67,7 @@ Provides-Extra: polars
|
|
|
67
67
|
|
|
68
68
|
Package ``apache-airflow-providers-common-sql``
|
|
69
69
|
|
|
70
|
-
Release: ``1.30.
|
|
70
|
+
Release: ``1.30.2``
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
`Common SQL Provider <https://en.wikipedia.org/wiki/SQL>`__
|
|
@@ -80,7 +80,7 @@ This is a provider package for ``common.sql`` provider. All classes for this pro
|
|
|
80
80
|
are in ``airflow.providers.common.sql`` python package.
|
|
81
81
|
|
|
82
82
|
You can find package information and changelog for the provider
|
|
83
|
-
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-common-sql/1.30.
|
|
83
|
+
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-common-sql/1.30.2/>`_.
|
|
84
84
|
|
|
85
85
|
Installation
|
|
86
86
|
------------
|
|
@@ -98,7 +98,7 @@ Requirements
|
|
|
98
98
|
PIP package Version required
|
|
99
99
|
========================================== ==================
|
|
100
100
|
``apache-airflow`` ``>=2.11.0``
|
|
101
|
-
``apache-airflow-providers-common-compat`` ``>=1.
|
|
101
|
+
``apache-airflow-providers-common-compat`` ``>=1.11.0``
|
|
102
102
|
``sqlparse`` ``>=0.5.1``
|
|
103
103
|
``more-itertools`` ``>=9.0.0``
|
|
104
104
|
``methodtools`` ``>=0.4.7``
|
|
@@ -136,5 +136,5 @@ Extra Dependencies
|
|
|
136
136
|
=============== ================================================================================================
|
|
137
137
|
|
|
138
138
|
The changelog for the provider package can be found in the
|
|
139
|
-
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-common-sql/1.30.
|
|
139
|
+
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-common-sql/1.30.2/changelog.html>`_.
|
|
140
140
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
airflow/providers/common/sql/README_API.md,sha256=Yug9-DLqoKkG-qT5XMwkyG_T-r17Iqhiipxt5tMZIUw,5906
|
|
2
|
-
airflow/providers/common/sql/__init__.py,sha256=
|
|
2
|
+
airflow/providers/common/sql/__init__.py,sha256=DA8yoEPQw1lBAQxFc_1oUzjM1cQHpECx8cilXMjiYCM,1500
|
|
3
3
|
airflow/providers/common/sql/get_provider_info.py,sha256=xCPXLKFA_1ilhGa0aB3E9ggdHtn9Do7Eb469begpZag,2767
|
|
4
4
|
airflow/providers/common/sql/get_provider_info.pyi,sha256=NSIGS74SESn-j0g3xd3BlctUrKlkWaXL605hCs0hjac,1580
|
|
5
5
|
airflow/providers/common/sql/version_compat.py,sha256=A6a37mMJVpSRlvL7wAMj4VGbFao3-lnRXMgnU3F3nLE,1676
|
|
@@ -12,21 +12,21 @@ airflow/providers/common/sql/doc/adr/0003-introduce-notion-of-dialects-in-dbapih
|
|
|
12
12
|
airflow/providers/common/sql/hooks/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
13
13
|
airflow/providers/common/sql/hooks/handlers.py,sha256=XjvycIQsGpDrtg6RFACczybW_dER97RR6Z6B_S6jf6Y,3399
|
|
14
14
|
airflow/providers/common/sql/hooks/handlers.pyi,sha256=Qex63GfW0J6RQeT-prAfukvw4NE6P1IQnM1e04D2sH4,1811
|
|
15
|
-
airflow/providers/common/sql/hooks/sql.py,sha256=
|
|
15
|
+
airflow/providers/common/sql/hooks/sql.py,sha256=GYn6q4wIBlf1RqmRakhjCiDnURqs_NuxvnTskGjyaOI,43933
|
|
16
16
|
airflow/providers/common/sql/hooks/sql.pyi,sha256=K7WXuEYXtzrdyBD4zDk7khEO8Wken5fTD1YGqeAOkFk,7916
|
|
17
17
|
airflow/providers/common/sql/operators/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
18
|
-
airflow/providers/common/sql/operators/generic_transfer.py,sha256=
|
|
19
|
-
airflow/providers/common/sql/operators/generic_transfer.pyi,sha256=
|
|
20
|
-
airflow/providers/common/sql/operators/sql.py,sha256=
|
|
18
|
+
airflow/providers/common/sql/operators/generic_transfer.py,sha256=4FRcbvCoL0T_a2pU-Sw4Z29zh-OXpp8iknXybe-iAl0,8494
|
|
19
|
+
airflow/providers/common/sql/operators/generic_transfer.pyi,sha256=pQ0nRbzB4hjUbjKsEc6mFd3_XuPAjlqwhU2ogyHlSI4,3303
|
|
20
|
+
airflow/providers/common/sql/operators/sql.py,sha256=P2TS0Qkto8uP3JNzMoK7C3MNx0l1bcwO6kEj45DZTWw,57720
|
|
21
21
|
airflow/providers/common/sql/sensors/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
22
|
-
airflow/providers/common/sql/sensors/sql.py,sha256=
|
|
23
|
-
airflow/providers/common/sql/sensors/sql.pyi,sha256=
|
|
22
|
+
airflow/providers/common/sql/sensors/sql.py,sha256=e_aTJbmXv3wX8yRzZzCUp4MnAUCTx88hT_3Zar3qpso,5440
|
|
23
|
+
airflow/providers/common/sql/sensors/sql.pyi,sha256=2NC2oxVxhHgUN2elwd06CSdMhgX1nJwJI_4YCRXsZc4,2486
|
|
24
24
|
airflow/providers/common/sql/triggers/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
25
|
-
airflow/providers/common/sql/triggers/sql.py,sha256=
|
|
25
|
+
airflow/providers/common/sql/triggers/sql.py,sha256=8dHrYYOziwyRdNuQfFj7lX2lImYRC2waU6YevhFAgls,3652
|
|
26
26
|
airflow/providers/common/sql/triggers/sql.pyi,sha256=TjSM2B3qCv3oN8Y5l_czi9YfxRE2h5Hv_lvUokeiGsE,1968
|
|
27
|
-
apache_airflow_providers_common_sql-1.30.
|
|
28
|
-
apache_airflow_providers_common_sql-1.30.
|
|
29
|
-
apache_airflow_providers_common_sql-1.30.
|
|
30
|
-
apache_airflow_providers_common_sql-1.30.
|
|
31
|
-
apache_airflow_providers_common_sql-1.30.
|
|
32
|
-
apache_airflow_providers_common_sql-1.30.
|
|
27
|
+
apache_airflow_providers_common_sql-1.30.2.dist-info/entry_points.txt,sha256=h8UXRp2crPuGmYVYRM5oe168qIh7g-4t2QQbVMizKjI,106
|
|
28
|
+
apache_airflow_providers_common_sql-1.30.2.dist-info/licenses/LICENSE,sha256=gXPVwptPlW1TJ4HSuG5OMPg-a3h43OGMkZRR1rpwfJA,10850
|
|
29
|
+
apache_airflow_providers_common_sql-1.30.2.dist-info/licenses/NOTICE,sha256=E3-_E02gwwSEFzeeWPKmnIjOoos3hW28CLISV6sYrbQ,168
|
|
30
|
+
apache_airflow_providers_common_sql-1.30.2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
31
|
+
apache_airflow_providers_common_sql-1.30.2.dist-info/METADATA,sha256=7fCHRjz6-tnyzxyvtSnCf3wlZETHG2MkW5i5FYmhltc,6574
|
|
32
|
+
apache_airflow_providers_common_sql-1.30.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|