Skip to content

Commit a742ad6

Browse files
authored
Merge pull request #724 from atlanhq/DQ-164
DQ-164 | Add support for rule conditions and incremental for DQ rules
2 parents c181d51 + ecb563c commit a742ad6

12 files changed

Lines changed: 941 additions & 35 deletions

File tree

pyatlan/client/asset.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,6 +1782,33 @@ def add_dq_rule_schedule(
17821782
response = self.save(updated_asset)
17831783
return response
17841784

1785+
@validate_arguments
1786+
def set_dq_row_scope_filter_column(
1787+
self,
1788+
asset_type: Type[A],
1789+
asset_name: str,
1790+
asset_qualified_name: str,
1791+
row_scope_filter_column_qualified_name: str,
1792+
) -> AssetMutationResponse:
1793+
"""
1794+
Set the row scope filter column for data quality rules on an asset.
1795+
1796+
:param asset_type: the type of asset to update (e.g., Table)
1797+
:param asset_name: the name of the asset to update
1798+
:param asset_qualified_name: the qualified name of the asset to update
1799+
:param row_scope_filter_column_qualified_name: the qualified name of the column to use for row scope filtering
1800+
:returns: the result of the save
1801+
:raises AtlanError: on any API communication issue
1802+
"""
1803+
updated_asset = asset_type.updater(
1804+
qualified_name=asset_qualified_name, name=asset_name
1805+
)
1806+
updated_asset.alpha_asset_d_q_row_scope_filter_column_qualified_name = (
1807+
row_scope_filter_column_qualified_name
1808+
)
1809+
response = self.save(updated_asset)
1810+
return response
1811+
17851812

17861813
class SearchResults(ABC, Iterable):
17871814
"""

pyatlan/errors.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,27 @@ class ErrorCode(Enum):
647647
"Ensure your product instance has a valid `data_product_assets_d_s_l` value before making the request.",
648648
InvalidRequestError,
649649
)
650+
DQ_RULE_TYPE_NOT_SUPPORTED = (
651+
400,
652+
"ATLAN-PYTHON-400-073",
653+
"Rule type '{0}' does not support {1}.",
654+
"Choose a rule type that supports the specified template configuration.",
655+
InvalidRequestError,
656+
)
657+
DQ_RULE_CONDITIONS_INVALID = (
658+
400,
659+
"ATLAN-PYTHON-400-074",
660+
"Invalid rule conditions: {0}.",
661+
"Ensure your rule conditions are valid and match the expected format.",
662+
InvalidRequestError,
663+
)
664+
DQ_ROW_SCOPE_FILTER_COLUMN_MISSING = (
665+
400,
666+
"ATLAN-PYTHON-400-075",
667+
"Row scope filter column not configured for asset '{0}'.",
668+
"Use client.asset.set_dq_row_scope_filter_column() to configure the row scope filter column first.",
669+
InvalidRequestError,
670+
)
650671
AUTHENTICATION_PASSTHROUGH = (
651672
401,
652673
"ATLAN-PYTHON-401-000",

pyatlan/generator/templates/methods/asset/alpha__d_q_rule.jinja2

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,17 @@
113113
alert_priority: alpha_DQRuleAlertPriority,
114114
threshold_compare_operator: Optional[
115115
alpha_DQRuleThresholdCompareOperator
116-
] = alpha_DQRuleThresholdCompareOperator.LESS_THAN_EQUAL,
116+
] = None,
117117
threshold_unit: Optional[alpha_DQRuleThresholdUnit] = None,
118+
rule_conditions: Optional[str] = None,
119+
row_scope_filtering_enabled: Optional[bool] = False,
118120
) -> alpha_DQRule:
119121
validate_required_fields(
120122
[
121123
"client",
122124
"rule_type",
123125
"asset",
124126
"column",
125-
"threshold_compare_operator",
126127
"threshold_value",
127128
"alert_priority",
128129
],
@@ -131,25 +132,59 @@
131132
rule_type,
132133
asset,
133134
column,
134-
threshold_compare_operator,
135135
threshold_value,
136136
alert_priority,
137137
],
138138
)
139+
template_config = client.dq_template_config_cache.get_template_config(rule_type)
140+
141+
asset_for_validation = asset
142+
if row_scope_filtering_enabled and asset.qualified_name:
143+
from pyatlan.model.fluent_search import FluentSearch
144+
145+
search_request = (
146+
FluentSearch()
147+
.where(Asset.QUALIFIED_NAME.eq(asset.qualified_name))
148+
.include_on_results(
149+
Asset.ALPHAASSET_DQ_ROW_SCOPE_FILTER_COLUMN_QUALIFIED_NAME
150+
)
151+
).to_request()
152+
results = client.asset.search(search_request)
153+
if results.count == 1:
154+
asset_for_validation = results.current_page()[0]
155+
156+
validated_threshold_operator = (
157+
alpha_DQRule.Attributes._validate_template_features(
158+
rule_type,
159+
rule_conditions,
160+
row_scope_filtering_enabled,
161+
template_config,
162+
threshold_compare_operator,
163+
asset_for_validation,
164+
)
165+
)
166+
167+
final_threshold_compare_operator = (
168+
validated_threshold_operator
169+
or threshold_compare_operator
170+
or alpha_DQRuleThresholdCompareOperator.LESS_THAN_EQUAL
171+
)
139172

140173
attributes = alpha_DQRule.Attributes.creator(
141174
client=client,
142175
rule_type=rule_type,
143176
asset=asset,
144177
column=column,
145-
threshold_compare_operator=threshold_compare_operator,
178+
threshold_compare_operator=final_threshold_compare_operator,
146179
threshold_value=threshold_value,
147180
alert_priority=alert_priority,
148181
threshold_unit=threshold_unit,
149182
rule_name=None,
150183
dimension=None,
151184
custom_sql=None,
152185
description=None,
186+
rule_conditions=rule_conditions,
187+
row_scope_filtering_enabled=row_scope_filtering_enabled,
153188
)
154189
return cls(attributes=attributes)
155190

@@ -169,6 +204,8 @@
169204
custom_sql: Optional[str] = None,
170205
rule_name: Optional[str] = None,
171206
description: Optional[str] = None,
207+
rule_conditions: Optional[str] = None,
208+
row_scope_filtering_enabled: Optional[bool] = False,
172209
) -> SelfAsset:
173210
from pyatlan.model.fluent_search import FluentSearch
174211

@@ -190,6 +227,7 @@
190227
.include_on_results(alpha_DQRule.USER_DESCRIPTION)
191228
.include_on_results(alpha_DQRule.ALPHADQ_RULE_DIMENSION)
192229
.include_on_results(alpha_DQRule.ALPHADQ_RULE_CONFIG_ARGUMENTS)
230+
.include_on_results(alpha_DQRule.ALPHADQ_RULE_ROW_SCOPE_FILTERING_ENABLED)
193231
.include_on_results(alpha_DQRule.ALPHADQ_RULE_SOURCE_SYNC_STATUS)
194232
.include_on_results(alpha_DQRule.ALPHADQ_RULE_STATUS)
195233
).to_request()
@@ -208,6 +246,9 @@
208246
retrieved_dimension = search_result.alpha_dq_rule_dimension # type: ignore[attr-defined]
209247
retrieved_column = search_result.alpha_dq_rule_base_column # type: ignore[attr-defined]
210248
retrieved_alert_priority = search_result.alpha_dq_rule_alert_priority # type: ignore[attr-defined]
249+
retrieved_row_scope_filtering_enabled = (
250+
search_result.alpha_dq_rule_row_scope_filtering_enabled # type: ignore[attr-defined]
251+
)
211252
retrieved_description = search_result.user_description
212253
retrieved_asset = search_result.alpha_dq_rule_base_dataset # type: ignore[attr-defined]
213254
retrieved_template_rule_name = search_result.alpha_dq_rule_template_name # type: ignore[attr-defined]
@@ -234,35 +275,60 @@
234275
else None
235276
) # type: ignore[attr-defined]
236277

278+
retrieved_rule_type = retrieved_template_rule_name
279+
template_config = client.dq_template_config_cache.get_template_config(
280+
retrieved_rule_type
281+
)
282+
validated_threshold_operator = (
283+
alpha_DQRule.Attributes._validate_template_features(
284+
retrieved_rule_type,
285+
rule_conditions,
286+
row_scope_filtering_enabled,
287+
template_config,
288+
threshold_compare_operator or retrieved_threshold_compare_operator,
289+
retrieved_asset,
290+
)
291+
)
292+
293+
final_compare_operator = (
294+
validated_threshold_operator
295+
or threshold_compare_operator
296+
or retrieved_threshold_compare_operator
297+
or alpha_DQRuleThresholdCompareOperator.LESS_THAN_EQUAL
298+
)
299+
237300
config_arguments_raw = alpha_DQRule.Attributes._generate_config_arguments_raw(
238301
is_alert_enabled=True,
239302
custom_sql=custom_sql or retrieved_custom_sql,
240303
display_name=rule_name or retrieved_rule_name,
241304
dimension=dimension or retrieved_dimension,
242-
compare_operator=threshold_compare_operator
243-
or retrieved_threshold_compare_operator,
305+
compare_operator=final_compare_operator,
244306
threshold_value=threshold_value or retrieved_threshold_value,
245307
threshold_unit=threshold_unit or retrieved_threshold_unit,
246308
column=retrieved_column,
247309
dq_priority=alert_priority or retrieved_alert_priority,
248310
description=description or retrieved_description,
311+
rule_conditions=rule_conditions,
312+
row_scope_filtering_enabled=row_scope_filtering_enabled,
249313
)
250314

251315
attr_dq = cls.Attributes(
252316
name="",
253317
alpha_dq_rule_config_arguments=alpha_DQRuleConfigArguments(
254318
alpha_dq_rule_threshold_object=alpha_DQRuleThresholdObject(
255-
alpha_dq_rule_threshold_compare_operator=threshold_compare_operator
256-
or retrieved_threshold_compare_operator,
319+
alpha_dq_rule_threshold_compare_operator=final_compare_operator,
257320
alpha_dq_rule_threshold_value=threshold_value
258321
or retrieved_threshold_value,
259322
alpha_dq_rule_threshold_unit=threshold_unit
260323
or retrieved_threshold_unit,
261324
),
262325
alpha_dq_rule_config_arguments_raw=config_arguments_raw,
326+
alpha_dq_rule_config_rule_conditions=rule_conditions,
263327
),
264328
alpha_dq_rule_base_dataset_qualified_name=retrieved_asset.qualified_name,
265329
alpha_dq_rule_alert_priority=alert_priority or retrieved_alert_priority,
330+
alpha_dq_rule_row_scope_filtering_enabled=row_scope_filtering_enabled
331+
or retrieved_row_scope_filtering_enabled,
266332
alpha_dq_rule_base_dataset=retrieved_asset,
267333
qualified_name=qualified_name,
268334
alpha_dq_rule_dimension=dimension or retrieved_dimension,

0 commit comments

Comments
 (0)