icsDataValidation 1.0.378__py3-none-any.whl → 1.0.419__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.
- icsDataValidation/configuration.py +0 -0
- icsDataValidation/connection_setups/__init__.py +0 -0
- icsDataValidation/connection_setups/azure_connection_setup.py +2 -1
- icsDataValidation/connection_setups/databricks_connection_setup.py +0 -0
- icsDataValidation/connection_setups/exasol_connection_setup.py +0 -0
- icsDataValidation/connection_setups/oracle_connection_setup.py +0 -0
- icsDataValidation/connection_setups/snowflake_connection_setup.py +0 -0
- icsDataValidation/connection_setups/sqlserver_connection_setup.py +20 -0
- icsDataValidation/connection_setups/teradata_connection_setup.py +0 -0
- icsDataValidation/core/__init__.py +0 -0
- icsDataValidation/core/database_objects.py +0 -0
- icsDataValidation/core/object_comparison.py +0 -0
- icsDataValidation/input_parameters/__init__.py +0 -0
- icsDataValidation/input_parameters/testing_tool_params.py +4 -3
- icsDataValidation/main.py +15 -11
- icsDataValidation/output_parameters/__init__.py +0 -0
- icsDataValidation/output_parameters/result_params.py +0 -0
- icsDataValidation/services/__init__.py +0 -0
- icsDataValidation/services/comparison_service.py +101 -82
- icsDataValidation/services/database_services/__init__.py +0 -0
- icsDataValidation/services/database_services/azure_service.py +69 -43
- icsDataValidation/services/database_services/databricks_hive_metastore_service.py +20 -7
- icsDataValidation/services/database_services/databricks_unity_catalog_service.py +20 -12
- icsDataValidation/services/database_services/exasol_service.py +26 -23
- icsDataValidation/services/database_services/oracle_service.py +64 -55
- icsDataValidation/services/database_services/snowflake_service.py +85 -36
- icsDataValidation/services/database_services/sqlserver_service.py +868 -0
- icsDataValidation/services/database_services/teradata_service.py +54 -37
- icsDataValidation/services/initialization_service.py +0 -0
- icsDataValidation/services/result_service.py +0 -0
- icsDataValidation/services/system_service.py +4 -0
- icsDataValidation/services/testset_service.py +0 -0
- icsDataValidation/utils/__init__.py +0 -0
- icsDataValidation/utils/file_util.py +0 -0
- icsDataValidation/utils/logger_util.py +0 -0
- icsDataValidation/utils/pandas_util.py +0 -0
- icsDataValidation/utils/parallelization_util.py +0 -0
- icsDataValidation/utils/sql_util.py +0 -0
- icsdatavalidation-1.0.419.dist-info/METADATA +20 -0
- {icsDataValidation-1.0.378.dist-info → icsdatavalidation-1.0.419.dist-info}/RECORD +18 -18
- {icsDataValidation-1.0.378.dist-info → icsdatavalidation-1.0.419.dist-info}/WHEEL +1 -1
- icsdatavalidation-1.0.419.dist-info/top_level.txt +1 -0
- examples/ics_data_validation.py +0 -7
- examples/manual_execution_params.template.py +0 -44
- icsDataValidation-1.0.378.dist-info/METADATA +0 -20
- icsDataValidation-1.0.378.dist-info/top_level.txt +0 -4
|
@@ -110,7 +110,7 @@ class TeradataService(object):
|
|
|
110
110
|
try:
|
|
111
111
|
|
|
112
112
|
row_count = self.execute_queries(query_get_row_count).fetchall()[0][0]
|
|
113
|
-
|
|
113
|
+
|
|
114
114
|
except Exception as err:
|
|
115
115
|
error_list.append(str(err))
|
|
116
116
|
error_list.append(query_get_row_count)
|
|
@@ -143,16 +143,17 @@ class TeradataService(object):
|
|
|
143
143
|
|
|
144
144
|
return results
|
|
145
145
|
|
|
146
|
-
def get_count_distincts_from_object(self, object : DatabaseObject, column_intersections: list, where_clause: str="", exclude_columns:list=[]
|
|
146
|
+
def get_count_distincts_from_object(self, object : DatabaseObject, column_intersections: list, where_clause: str="", exclude_columns:list=[],
|
|
147
|
+
enclose_column_by_double_quotes: bool = False) -> dict:
|
|
147
148
|
|
|
148
149
|
if self.teradata_connection is None:
|
|
149
150
|
self._connect_to_teradata()
|
|
150
|
-
|
|
151
|
+
|
|
151
152
|
unions=""
|
|
152
153
|
for column in column_intersections:
|
|
153
154
|
if column not in exclude_columns:
|
|
154
155
|
unions +=f"UNION SELECT CAST('{column}' AS VARCHAR(500)) AS COLUMN_NAME, COUNT(DISTINCT {column}) AS COUNT_DISTINCT FROM {object.schema}.{object.name} {where_clause}"
|
|
155
|
-
|
|
156
|
+
|
|
156
157
|
query_get_count_distincts_from_object=f"{unions[5:]} ORDER BY 2;"
|
|
157
158
|
error_list = []
|
|
158
159
|
dict_count_distincts = []
|
|
@@ -167,7 +168,7 @@ class TeradataService(object):
|
|
|
167
168
|
}
|
|
168
169
|
|
|
169
170
|
dict_count_distincts.append(single_dict)
|
|
170
|
-
|
|
171
|
+
|
|
171
172
|
except Exception as err:
|
|
172
173
|
#raise err
|
|
173
174
|
error_list.append(["ERROR", str(err).split('|||')[0], str(err).split('|||')[1]])
|
|
@@ -182,7 +183,8 @@ class TeradataService(object):
|
|
|
182
183
|
|
|
183
184
|
return size
|
|
184
185
|
|
|
185
|
-
def create_checksums(self, object: DatabaseObject, column_intersections: list, where_clause:str="", exclude_columns:list=[]
|
|
186
|
+
def create_checksums(self, object: DatabaseObject, column_intersections: list, where_clause:str="", exclude_columns:list=[],
|
|
187
|
+
enclose_column_by_double_quotes: bool = False) -> List[Dict]:
|
|
186
188
|
|
|
187
189
|
if self.teradata_connection is None:
|
|
188
190
|
self._connect_to_teradata()
|
|
@@ -212,7 +214,7 @@ class TeradataService(object):
|
|
|
212
214
|
elif column_datatype.lower() == 'i1' and 1 == 0:
|
|
213
215
|
aggregates += f", (SELECT CONCAT ((select trim(count(*)) as val FROM {object.schema}.{object.name} WHERE {column} = 1),'_',(select trim(count(*)) as val from {object.schema}.{object.name} WHERE {column} = 0))) AS aggregateboolean_{column}"
|
|
214
216
|
#else: Additional Data Types: ++ TD_ANYTYPE, a1 ARRAY, AN ARRAY , bo BINARY LARGE OBJECT, us USER‑DEFINED TYPE (all types),xm XML
|
|
215
|
-
|
|
217
|
+
|
|
216
218
|
query_checksums = f"select {aggregates[1:]} from {object.schema}.{object.name} {where_clause};"
|
|
217
219
|
|
|
218
220
|
query_countnulls = f"select {count_nulls[1:]} from {object.schema}.{object.name} {where_clause};"
|
|
@@ -257,7 +259,19 @@ class TeradataService(object):
|
|
|
257
259
|
return checksums
|
|
258
260
|
|
|
259
261
|
|
|
260
|
-
def create_pandas_df_from_group_by(
|
|
262
|
+
def create_pandas_df_from_group_by(
|
|
263
|
+
self,
|
|
264
|
+
object: DatabaseObject,
|
|
265
|
+
column_intersections: list,
|
|
266
|
+
group_by_columns: list,
|
|
267
|
+
group_by_aggregation_columns: list,
|
|
268
|
+
group_by_aggregation_type: str,
|
|
269
|
+
only_numeric: bool,
|
|
270
|
+
where_clause: str,
|
|
271
|
+
exclude_columns: list,
|
|
272
|
+
numeric_scale: int=None,
|
|
273
|
+
enclose_column_by_double_quotes: bool = False
|
|
274
|
+
) -> List[Dict]:
|
|
261
275
|
|
|
262
276
|
if self.teradata_connection is None:
|
|
263
277
|
self._connect_to_teradata()
|
|
@@ -267,7 +281,7 @@ class TeradataService(object):
|
|
|
267
281
|
else:
|
|
268
282
|
aggregation_columns= [f"{column.upper()}" for column in column_intersections if (column in group_by_aggregation_columns and column not in exclude_columns)]
|
|
269
283
|
|
|
270
|
-
dict_colummns_datatype_grouping=self.get_data_types_from_object(object, group_by_columns)
|
|
284
|
+
dict_colummns_datatype_grouping=self.get_data_types_from_object(object, group_by_columns)
|
|
271
285
|
|
|
272
286
|
group_by_query_columns_string = " "
|
|
273
287
|
grouping_columns_final = []
|
|
@@ -286,7 +300,7 @@ class TeradataService(object):
|
|
|
286
300
|
|
|
287
301
|
group_by_query_columns_string = group_by_query_columns_string[:-1]
|
|
288
302
|
|
|
289
|
-
dict_colummns_datatype=self.get_data_types_from_object(object, aggregation_columns)
|
|
303
|
+
dict_colummns_datatype=self.get_data_types_from_object(object, aggregation_columns)
|
|
290
304
|
|
|
291
305
|
aggregates = ""
|
|
292
306
|
aggregates_min = ""
|
|
@@ -294,15 +308,15 @@ class TeradataService(object):
|
|
|
294
308
|
for column in aggregation_columns:
|
|
295
309
|
column_datatype=next(x for x in dict_colummns_datatype if x["COLUMN_NAME"] == column)["DATA_TYPE"]
|
|
296
310
|
column_datatype = column_datatype.split('(')[0]
|
|
297
|
-
|
|
311
|
+
|
|
298
312
|
if column_datatype.lower() == 'i8' or column_datatype.lower() == 'i1' or column_datatype.lower() == 'i' or column_datatype.lower() == 'i2':
|
|
299
|
-
|
|
313
|
+
|
|
300
314
|
if not numeric_scale:
|
|
301
315
|
aggregates += f", sum(cast ({column} as decimal(30,0))) as sum_{column}"
|
|
302
316
|
else:
|
|
303
317
|
aggregates += f", CASE WHEN TRIM(TO_CHAR(CAST(ROUND(sum(cast ({column} as decimal(30,0))), {numeric_scale}) as decimal(38,{numeric_scale})), '999999999999999999.{'0'*numeric_scale}')) like '.%' THEN '0' || TRIM(TO_CHAR(CAST(ROUND(sum(cast ({column} as decimal(30,0))), {numeric_scale}) as decimal(38,{numeric_scale})), '999999999999999999.{'0'*numeric_scale}')) ELSE TRIM(TO_CHAR(CAST(ROUND(sum(cast ({column} as decimal(30,0))), {numeric_scale}) as decimal(38,{numeric_scale})), '999999999999999999.{'0'*numeric_scale}')) END as SUM_{column}"
|
|
304
318
|
aggregates_min += f", CASE WHEN TRIM(TO_CHAR(CAST(ROUND(min({column}), {numeric_scale}) as decimal(38,{numeric_scale})), '999999999999999999.{'0'*numeric_scale}')) like '.%' THEN '0' || TRIM(TO_CHAR(CAST(ROUND(min({column}), {numeric_scale}) as decimal(38,{numeric_scale})), '999999999999999999.{'0'*numeric_scale}')) ELSE TRIM(TO_CHAR(CAST(ROUND(min({column}), {numeric_scale}) as decimal(38,{numeric_scale})), '999999999999999999.{'0'*numeric_scale}')) END as MIN_{column}, CASE WHEN TRIM(TO_CHAR(CAST(ROUND(max({column}), {numeric_scale}) as decimal(38,{numeric_scale})), '999999999999999999.{'0'*numeric_scale}')) like '.%' THEN '0' || TRIM(TO_CHAR(CAST(ROUND(max({column}), {numeric_scale}) as decimal(38,{numeric_scale})), '999999999999999999.{'0'*numeric_scale}')) ELSE TRIM(TO_CHAR(CAST(ROUND(max({column}), {numeric_scale}) as decimal(38,{numeric_scale})), '999999999999999999.{'0'*numeric_scale}')) END as MAX_{column}"
|
|
305
|
-
|
|
319
|
+
|
|
306
320
|
elif column_datatype.lower() == 'bf' or column_datatype.lower() == 'bv' or column_datatype.lower() == 'd' or column_datatype.lower() == 'f' or column_datatype.lower() == 'dy' or column_datatype.lower() == 'dh' or column_datatype.lower() == 'dm' or column_datatype.lower() == 'ds' or column_datatype.lower() == 'hr' or column_datatype.lower() == 'hs' or column_datatype.lower() == 'mi' or column_datatype.lower() == 'ms' or column_datatype.lower() == 'mo' or column_datatype.lower() == 'sc' or column_datatype.lower() == 'yr' or column_datatype.lower() == 'ym' or column_datatype.lower() == 'n' or column_datatype.lower() == 'd' :
|
|
307
321
|
if not numeric_scale:
|
|
308
322
|
aggregates += f", sum(({column} )) as sum_{column}"
|
|
@@ -313,15 +327,15 @@ class TeradataService(object):
|
|
|
313
327
|
|
|
314
328
|
|
|
315
329
|
elif not only_numeric and ( column_datatype.lower() == 'da' or column_datatype.lower() == 'pd' or column_datatype.lower() == 'pt' or column_datatype.lower() == 'pz' or column_datatype.lower() == 'pm' or column_datatype.lower() == 'at' or column_datatype.lower() == 'ts' or column_datatype.lower() == 'tz' or column_datatype.lower() == 'sz'):
|
|
316
|
-
|
|
330
|
+
|
|
317
331
|
aggregates += f", count(distinct {column}) as COUNTDISTINCT_{column}"
|
|
318
332
|
aggregates_min += f", min({column}) as MIN_{column}, max({column}) as MAX_{column}"
|
|
319
333
|
|
|
320
334
|
elif not only_numeric and (column_datatype.lower() == 'cv' or column_datatype.lower() == 'cf' or column_datatype.lower() == 'co'):
|
|
321
|
-
|
|
335
|
+
|
|
322
336
|
aggregates += f", count(distinct {column}) as COUNTDISTINCT_{column}"
|
|
323
337
|
aggregates_min += f", min(TRIM({column})) as MIN_{column}, max(TRIM({column})) as MAX_{column}"
|
|
324
|
-
|
|
338
|
+
|
|
325
339
|
elif not only_numeric and column_datatype.lower() == 'i1' and 1 == 0:
|
|
326
340
|
|
|
327
341
|
aggregates += f", (SELECT CONCAT ((select trim(count(*)) as val FROM {object.schema}.{object.name} WHERE {column} = 1),'_',(select trim(count(*)) as val from {object.schema}.{object.name} WHERE {column} = 0))) AS AGGREGATEBOOLEAN_{column}"
|
|
@@ -367,7 +381,8 @@ class TeradataService(object):
|
|
|
367
381
|
return group_by_aggregation_pdf, group_by_query_aggregation_string, group_by_query_columns_string, grouping_columns_final, error_dict
|
|
368
382
|
|
|
369
383
|
|
|
370
|
-
def create_pandas_df(self, object : DatabaseObject, intersection_columns_trgt_src: list, where_clause:str="", exclude_columns:list=[]
|
|
384
|
+
def create_pandas_df(self, object : DatabaseObject, intersection_columns_trgt_src: list, where_clause:str="", exclude_columns:list=[],
|
|
385
|
+
enclose_column_by_double_quotes: bool = False) -> pd.DataFrame:
|
|
371
386
|
|
|
372
387
|
if self.teradata_connection is None:
|
|
373
388
|
self._connect_to_teradata()
|
|
@@ -379,8 +394,10 @@ class TeradataService(object):
|
|
|
379
394
|
src_pdf = self.execute_queries(df_query,True)
|
|
380
395
|
|
|
381
396
|
return src_pdf
|
|
382
|
-
|
|
383
|
-
def create_pandas_df_from_sample(self, object: DatabaseObject, column_intersections: list, key_columns: list, where_clause: str="", exclude_columns:list=[], key_filters: dict={}, dedicated_columns: list=[], sample_count :int=10
|
|
397
|
+
|
|
398
|
+
def create_pandas_df_from_sample(self, object: DatabaseObject, column_intersections: list, key_columns: list, where_clause: str="", exclude_columns:list=[], key_filters: dict={}, dedicated_columns: list=[], sample_count :int=10,
|
|
399
|
+
numeric_scale: int = None,
|
|
400
|
+
enclose_column_by_double_quotes: bool = False) -> List[Dict]:
|
|
384
401
|
|
|
385
402
|
if self.teradata_connection is None:
|
|
386
403
|
self._connect_to_teradata()
|
|
@@ -416,12 +433,12 @@ class TeradataService(object):
|
|
|
416
433
|
for column in dedicated_intersection:
|
|
417
434
|
column_datatype=next(x for x in dict_colummns_datatype if x["COLUMN_NAME"] == column)["DATA_TYPE"]
|
|
418
435
|
column_datatype = column_datatype.split('(')[0]
|
|
419
|
-
|
|
436
|
+
|
|
420
437
|
if column_datatype.lower() == 'i8' or column_datatype.lower() == 'i1' or column_datatype.lower() == 'i' or column_datatype.lower() == 'i2':
|
|
421
438
|
column_intersecions_new.append(f"CASE WHEN TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) like '.%' THEN '0' || TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) ELSE TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) END as {column}")
|
|
422
439
|
used_columns.append(column)
|
|
423
440
|
numeric_columns.append(column)
|
|
424
|
-
|
|
441
|
+
|
|
425
442
|
elif column_datatype.lower() == 'bf' or column_datatype.lower() == 'bv' or column_datatype.lower() == 'd' or column_datatype.lower() == 'f' or column_datatype.lower() == 'dy' or column_datatype.lower() == 'dh' or column_datatype.lower() == 'dm' or column_datatype.lower() == 'ds' or column_datatype.lower() == 'hr' or column_datatype.lower() == 'hs' or column_datatype.lower() == 'mi' or column_datatype.lower() == 'ms' or column_datatype.lower() == 'mo' or column_datatype.lower() == 'sc' or column_datatype.lower() == 'yr' or column_datatype.lower() == 'ym' or column_datatype.lower() == 'n' or column_datatype.lower() == 'd' :
|
|
426
443
|
column_intersecions_new.append(f"CASE WHEN TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) like '.%' THEN '0' || TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) ELSE TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) END as {column}")
|
|
427
444
|
used_columns.append(column)
|
|
@@ -452,22 +469,22 @@ class TeradataService(object):
|
|
|
452
469
|
values = list(key_filters.values())
|
|
453
470
|
if values[0] == []:
|
|
454
471
|
sample_query = f"SELECT {columns} FROM {object.schema}.{object.name} SAMPLE {sample_count} {where_clause} ORDER BY {keys};"
|
|
455
|
-
else:
|
|
472
|
+
else:
|
|
456
473
|
where_clause = f'{where_clause} AND (('
|
|
457
474
|
print(key_filters)
|
|
458
475
|
for j in range(len(values[0])):
|
|
459
476
|
for key in key_filters.keys():
|
|
460
477
|
if key == 'TECH_ID' or key in numeric_columns:
|
|
461
|
-
where_clause += f" CAST(ROUND({key}, 2) as decimal(38,2)) = {str(key_filters[key][j])} AND"
|
|
462
|
-
else:
|
|
463
|
-
where_clause += f" {key} = '{str(key_filters[key][j])}' AND"
|
|
478
|
+
where_clause += f" CAST(ROUND({key}, 2) as decimal(38,2)) = {str(key_filters[key][j])} AND"
|
|
479
|
+
else:
|
|
480
|
+
where_clause += f" {key} = '{str(key_filters[key][j])}' AND"
|
|
464
481
|
where_clause = f" {where_clause[:-3]}) OR ("
|
|
465
482
|
where_clause = f"{where_clause[:-4]})"
|
|
466
483
|
|
|
467
484
|
sample_query = f"SELECT {columns} FROM {object.schema}.{object.name} SAMPLE {sample_count} {where_clause} ORDER BY {keys};"
|
|
468
485
|
else:
|
|
469
486
|
sample_query = f"SELECT {columns} FROM {object.schema}.{object.name} SAMPLE {sample_count} {where_clause} ORDER BY {keys};"
|
|
470
|
-
|
|
487
|
+
|
|
471
488
|
elif key_intersection != [] and not is_dedicated:
|
|
472
489
|
column_intersecions_new = []
|
|
473
490
|
used_columns = []
|
|
@@ -477,13 +494,13 @@ class TeradataService(object):
|
|
|
477
494
|
for column in column_intersections:
|
|
478
495
|
column_datatype=next(x for x in dict_colummns_datatype if x["COLUMN_NAME"] == column)["DATA_TYPE"]
|
|
479
496
|
column_datatype = column_datatype.split('(')[0]
|
|
480
|
-
|
|
497
|
+
|
|
481
498
|
if column_datatype.lower() == 'i8' or column_datatype.lower() == 'i1' or column_datatype.lower() == 'i' or column_datatype.lower() == 'i2':
|
|
482
499
|
#TODO FFR - negativer Fall
|
|
483
500
|
column_intersecions_new.append(f"CASE WHEN TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) like '.%' THEN '0' || TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) ELSE TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) END as {column}")
|
|
484
501
|
used_columns.append(column)
|
|
485
502
|
numeric_columns.append(column)
|
|
486
|
-
|
|
503
|
+
|
|
487
504
|
elif column_datatype.lower() == 'bf' or column_datatype.lower() == 'bv' or column_datatype.lower() == 'd' or column_datatype.lower() == 'f' or column_datatype.lower() == 'dy' or column_datatype.lower() == 'dh' or column_datatype.lower() == 'dm' or column_datatype.lower() == 'ds' or column_datatype.lower() == 'hr' or column_datatype.lower() == 'hs' or column_datatype.lower() == 'mi' or column_datatype.lower() == 'ms' or column_datatype.lower() == 'mo' or column_datatype.lower() == 'sc' or column_datatype.lower() == 'yr' or column_datatype.lower() == 'ym' or column_datatype.lower() == 'n' or column_datatype.lower() == 'd' :
|
|
488
505
|
column_intersecions_new.append(f"CASE WHEN TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) like '.%' THEN '0' || TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) ELSE TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) END as {column}")
|
|
489
506
|
used_columns.append(column)
|
|
@@ -504,7 +521,7 @@ class TeradataService(object):
|
|
|
504
521
|
columns = columns[:-2]
|
|
505
522
|
keys = str(key_intersection)[1:-1].replace("'", "")
|
|
506
523
|
|
|
507
|
-
|
|
524
|
+
|
|
508
525
|
if key_filters == {}:
|
|
509
526
|
sample_query = f"SELECT {columns} FROM {object.schema}.{object.name} SAMPLE {sample_count} {where_clause} ORDER BY {keys};"
|
|
510
527
|
else:
|
|
@@ -525,7 +542,7 @@ class TeradataService(object):
|
|
|
525
542
|
# where_clause += " in " + in_clause
|
|
526
543
|
if values[0] == []:
|
|
527
544
|
sample_query = f"SELECT {columns} FROM {object.schema}.{object.name} SAMPLE {sample_count} {where_clause} ORDER BY {keys};"
|
|
528
|
-
else:
|
|
545
|
+
else:
|
|
529
546
|
where_clause = f'{where_clause} AND (('
|
|
530
547
|
print(key_filters)
|
|
531
548
|
for j in range(len(values[0])):
|
|
@@ -533,7 +550,7 @@ class TeradataService(object):
|
|
|
533
550
|
if key_filters.keys() in numeric_columns:
|
|
534
551
|
where_clause += f" {key} = {str(key_filters[key][j])} AND"
|
|
535
552
|
else:
|
|
536
|
-
where_clause += f" {key} = '{str(key_filters[key][j])}' AND"
|
|
553
|
+
where_clause += f" {key} = '{str(key_filters[key][j])}' AND"
|
|
537
554
|
where_clause += f" {where_clause[:-3]}) OR ("
|
|
538
555
|
where_clause = f"{where_clause[:-4]})"
|
|
539
556
|
|
|
@@ -552,17 +569,17 @@ class TeradataService(object):
|
|
|
552
569
|
print(dict_colummns_datatype)
|
|
553
570
|
column_datatype=next(x for x in dict_colummns_datatype if x["COLUMN_NAME"] == column)["DATA_TYPE"]
|
|
554
571
|
column_datatype = column_datatype.split('(')[0]
|
|
555
|
-
|
|
572
|
+
|
|
556
573
|
if column_datatype.lower() == 'i8' or column_datatype.lower() == 'i1' or column_datatype.lower() == 'i' or column_datatype.lower() == 'i2':
|
|
557
574
|
column_intersecions_new.append(f"CASE WHEN TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) like '.%' THEN '0' || TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) ELSE TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) END as {column}")
|
|
558
|
-
used_columns.append(column)
|
|
575
|
+
used_columns.append(column)
|
|
559
576
|
numeric_columns.append(column)
|
|
560
|
-
|
|
577
|
+
|
|
561
578
|
elif column_datatype.lower() == 'bf' or column_datatype.lower() == 'bv' or column_datatype.lower() == 'd' or column_datatype.lower() == 'f' or column_datatype.lower() == 'dy' or column_datatype.lower() == 'dh' or column_datatype.lower() == 'dm' or column_datatype.lower() == 'ds' or column_datatype.lower() == 'hr' or column_datatype.lower() == 'hs' or column_datatype.lower() == 'mi' or column_datatype.lower() == 'ms' or column_datatype.lower() == 'mo' or column_datatype.lower() == 'sc' or column_datatype.lower() == 'yr' or column_datatype.lower() == 'ym' or column_datatype.lower() == 'n' or column_datatype.lower() == 'd' :
|
|
562
579
|
column_intersecions_new.append(f"CASE WHEN TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) like '.%' THEN '0' || TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) ELSE TRIM(TO_CHAR(CAST(ROUND({column}, 2) as decimal(38,2)), '999999999999999999999999.00')) END as {column}")
|
|
563
|
-
used_columns.append(column)
|
|
580
|
+
used_columns.append(column)
|
|
564
581
|
numeric_columns.append(column)
|
|
565
|
-
|
|
582
|
+
|
|
566
583
|
elif column_datatype.lower() == 'cv' or column_datatype.lower() == 'cf' or column_datatype.lower() == 'cf':
|
|
567
584
|
column_intersecions_new.append(f'TRIM({column}) as decimal(38,2)) AS {column}')
|
|
568
585
|
used_columns.append(column)
|
|
@@ -662,4 +679,4 @@ class TeradataService(object):
|
|
|
662
679
|
_ = self.teradata_connection.execute(stripped_statement)
|
|
663
680
|
|
|
664
681
|
except Exception as err:
|
|
665
|
-
raise Exception(self._get_error_message(err, single_statement)) from err
|
|
682
|
+
raise Exception(self._get_error_message(err, single_statement)) from err
|
|
File without changes
|
|
File without changes
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from icsDataValidation.connection_setups.snowflake_connection_setup import load_snowflake_credentials
|
|
2
2
|
from icsDataValidation.connection_setups.exasol_connection_setup import load_exasol_credentials
|
|
3
3
|
from icsDataValidation.connection_setups.azure_connection_setup import load_azure_credentials
|
|
4
|
+
from icsDataValidation.connection_setups.sqlserver_connection_setup import load_sqlserver_credentials
|
|
4
5
|
from icsDataValidation.connection_setups.teradata_connection_setup import load_teradata_credentials
|
|
5
6
|
from icsDataValidation.connection_setups.oracle_connection_setup import load_oracle_credentials
|
|
6
7
|
from icsDataValidation.connection_setups.databricks_connection_setup import load_databricks_credentials
|
|
@@ -8,6 +9,7 @@ from icsDataValidation.services.database_services.snowflake_service import Snowf
|
|
|
8
9
|
from icsDataValidation.services.database_services.teradata_service import TeradataService
|
|
9
10
|
from icsDataValidation.services.database_services.exasol_service import ExasolService
|
|
10
11
|
from icsDataValidation.services.database_services.azure_service import AzureService
|
|
12
|
+
from icsDataValidation.services.database_services.sqlserver_service import SQLServerService
|
|
11
13
|
from icsDataValidation.services.database_services.oracle_service import OracleService
|
|
12
14
|
from icsDataValidation.services.database_services.databricks_hive_metastore_service import DatabricksHiveMetastoreService
|
|
13
15
|
from icsDataValidation.services.database_services.databricks_unity_catalog_service import DatabricksUnityCatalogService
|
|
@@ -33,6 +35,7 @@ class SystemService:
|
|
|
33
35
|
"SNOWFLAKE": load_snowflake_credentials,
|
|
34
36
|
"EXASOL": load_exasol_credentials,
|
|
35
37
|
"AZURE": load_azure_credentials,
|
|
38
|
+
"SQLSERVER": load_sqlserver_credentials,
|
|
36
39
|
"TERADATA": load_teradata_credentials,
|
|
37
40
|
"ORACLE": load_oracle_credentials,
|
|
38
41
|
"DATABRICKS_HIVE_METASTORE": load_databricks_credentials,
|
|
@@ -52,6 +55,7 @@ class SystemService:
|
|
|
52
55
|
"SNOWFLAKE": SnowflakeService,
|
|
53
56
|
"EXASOL": ExasolService,
|
|
54
57
|
"AZURE": AzureService,
|
|
58
|
+
"SQLSERVER": SQLServerService,
|
|
55
59
|
"TERADATA": TeradataService,
|
|
56
60
|
"ORACLE": OracleService,
|
|
57
61
|
"DATABRICKS_HIVE_METASTORE": DatabricksHiveMetastoreService,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: icsDataValidation
|
|
3
|
+
Version: 1.0.419
|
|
4
|
+
Summary: Add your description here
|
|
5
|
+
Author-email: initions <ICSMC_EXT_PYPIORG@accenture.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: azure-storage-blob==12.13.1
|
|
10
|
+
Requires-Dist: boto3==1.26.154
|
|
11
|
+
Requires-Dist: cloe-util-snowflake-connector==1.0.5
|
|
12
|
+
Requires-Dist: databricks-sdk==0.29.0
|
|
13
|
+
Requires-Dist: databricks-sql-connector==3.0.1
|
|
14
|
+
Requires-Dist: numpy==1.26.3
|
|
15
|
+
Requires-Dist: oracledb==2.5.0
|
|
16
|
+
Requires-Dist: pandas==2.2.2
|
|
17
|
+
Requires-Dist: pyexasol==0.24.0
|
|
18
|
+
Requires-Dist: pyodbc
|
|
19
|
+
Requires-Dist: python-dotenv>=1.0.1
|
|
20
|
+
Requires-Dist: teradatasql==17.20.0.10
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
examples/ics_data_validation.py,sha256=vyBAnU8yQGKGH33ZxrvaZpY-kt1iQ3h53kzkKG0Y7gI,139
|
|
2
|
-
examples/manual_execution_params.template.py,sha256=g3LAah1zEXJtozAZFpkxCm-JCWXSQY3R2SG-8YcPV9c,2038
|
|
3
1
|
icsDataValidation/configuration.py,sha256=HOFjmC8_e2nvoItndMtJQQA1MR5aCgZGeF1AwY_FvjE,477
|
|
4
|
-
icsDataValidation/main.py,sha256=
|
|
2
|
+
icsDataValidation/main.py,sha256=HGnQZ_A9Z4tdCloXs4Lap79LKVOkbmm1ethYbI0Qqlg,12582
|
|
5
3
|
icsDataValidation/connection_setups/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
icsDataValidation/connection_setups/azure_connection_setup.py,sha256=
|
|
4
|
+
icsDataValidation/connection_setups/azure_connection_setup.py,sha256=qxPvD-VZhdJqrdj06IVIk2Ud287YlLhE22Q5_oYKetM,790
|
|
7
5
|
icsDataValidation/connection_setups/databricks_connection_setup.py,sha256=dNEBum-8R-TUW2SCEk3CaNtCr_gLFvn456KBlENpgJU,1220
|
|
8
6
|
icsDataValidation/connection_setups/exasol_connection_setup.py,sha256=RfCUsL6G-NaOW-qNK-3SfHcljbRaKD6fDIHXkNQhClk,590
|
|
9
7
|
icsDataValidation/connection_setups/oracle_connection_setup.py,sha256=D-4ucC1ChE4HYm93ECIEg_yBOrn1NkknxFBgFRGFmWs,978
|
|
10
8
|
icsDataValidation/connection_setups/snowflake_connection_setup.py,sha256=IgEhni4Q0oYGh2QzptpyfEUvUt3cVO28jNSGg11cxyI,1778
|
|
9
|
+
icsDataValidation/connection_setups/sqlserver_connection_setup.py,sha256=ayRao5BbhkEJTteaeZiryz_GLC_6F_02XalvJDHM_4k,802
|
|
11
10
|
icsDataValidation/connection_setups/teradata_connection_setup.py,sha256=fIpuxz-FTqFK2vSMSuokqU9sdJkaJ4UP5piY_zIbj5k,624
|
|
12
11
|
icsDataValidation/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
12
|
icsDataValidation/core/database_objects.py,sha256=2oaDaVQajSYI_HJjJy1pmc6FsoK_wMfwgu6ZgEcFvow,523
|
|
14
13
|
icsDataValidation/core/object_comparison.py,sha256=OEz5m1pp_PbIWyM5998iB5obFKYdJEqDo9Z0Hpj7o4A,14988
|
|
15
14
|
icsDataValidation/input_parameters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
-
icsDataValidation/input_parameters/testing_tool_params.py,sha256=
|
|
15
|
+
icsDataValidation/input_parameters/testing_tool_params.py,sha256=trVZmxd2hsJRBWgdv0YePdaA9T20QbL3bOCVUOwIH18,6907
|
|
17
16
|
icsDataValidation/output_parameters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
17
|
icsDataValidation/output_parameters/result_params.py,sha256=5Mk9L9zWaxUqcKwLZQ539lVUp0b0s-YUmSA3PBgbqfs,2833
|
|
19
18
|
icsDataValidation/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
-
icsDataValidation/services/comparison_service.py,sha256=
|
|
19
|
+
icsDataValidation/services/comparison_service.py,sha256=xd3FuiJ9WN37pPTlEOzlVlq12_mjY6ny26vnYi-OhCw,44992
|
|
21
20
|
icsDataValidation/services/initialization_service.py,sha256=AHbJrq_LjMPFoeOJC2pi2ZZ1xkL8njSZn38psc3do60,6687
|
|
22
21
|
icsDataValidation/services/result_service.py,sha256=edD6aejIi5P7qDNHKnN46KrN5tfzwqnw5TB35SvFAWU,28396
|
|
23
|
-
icsDataValidation/services/system_service.py,sha256=
|
|
22
|
+
icsDataValidation/services/system_service.py,sha256=GErl_Zx_DaajXTTyfJJ5_xqpd2nLnfnRHcPDa_OVF58,3518
|
|
24
23
|
icsDataValidation/services/testset_service.py,sha256=k1wRjI4Ltw9fylek9iW8N6DvnXn13wf6IJ703qQDMEc,15363
|
|
25
24
|
icsDataValidation/services/database_services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
-
icsDataValidation/services/database_services/azure_service.py,sha256=
|
|
27
|
-
icsDataValidation/services/database_services/databricks_hive_metastore_service.py,sha256=
|
|
28
|
-
icsDataValidation/services/database_services/databricks_unity_catalog_service.py,sha256=
|
|
29
|
-
icsDataValidation/services/database_services/exasol_service.py,sha256=
|
|
30
|
-
icsDataValidation/services/database_services/oracle_service.py,sha256=
|
|
31
|
-
icsDataValidation/services/database_services/snowflake_service.py,sha256=
|
|
32
|
-
icsDataValidation/services/database_services/
|
|
25
|
+
icsDataValidation/services/database_services/azure_service.py,sha256=bAfpekHowj92qAm3C0hVyxwTpg5J3DoF82DdGKXoe6Q,16932
|
|
26
|
+
icsDataValidation/services/database_services/databricks_hive_metastore_service.py,sha256=JfI-6buw7PfK-gORiAaBx8koVdORfMZav1-w7q697NI,88177
|
|
27
|
+
icsDataValidation/services/database_services/databricks_unity_catalog_service.py,sha256=g7uMrPErjc6El9BmikDc3LmxwCCZnsuzxn4_hIJi7u0,70856
|
|
28
|
+
icsDataValidation/services/database_services/exasol_service.py,sha256=LdjU8mM77zTmNmhJPQrgQO-HwAZv0C0seYMDjuWU9BQ,11153
|
|
29
|
+
icsDataValidation/services/database_services/oracle_service.py,sha256=6t0tt0TJvre_1B5FVTFgCNZYgipT8zCtNngXMEnQi98,31826
|
|
30
|
+
icsDataValidation/services/database_services/snowflake_service.py,sha256=ryQ57NLnx8jWp3n2xP2E9sQs8bCshFjw17q6KVer9cc,63437
|
|
31
|
+
icsDataValidation/services/database_services/sqlserver_service.py,sha256=ApPCwuq8tmSq7vPsFhKzKaQnHUaZS5EoS77Nr8c1g-k,38476
|
|
32
|
+
icsDataValidation/services/database_services/teradata_service.py,sha256=h1UX-Wrf9qvZ_hXpH-Y63TRZ8csOCVcEjFn6ux7hvyk,40299
|
|
33
33
|
icsDataValidation/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
34
|
icsDataValidation/utils/file_util.py,sha256=ZTMB1sTnIIdffg9tEJRCFQQ5SG8Fksc5ie1PM4gHXG4,3432
|
|
35
35
|
icsDataValidation/utils/logger_util.py,sha256=xS48_FFMot_hyQgJY8DUeRTn5jpdvRt5QI6bvlV1jCY,3647
|
|
36
36
|
icsDataValidation/utils/pandas_util.py,sha256=D_g7Xw7BIS2E-1ZhJIvp62K5xuKjIkj-7TxH4HN_8SI,6505
|
|
37
37
|
icsDataValidation/utils/parallelization_util.py,sha256=6P0YcQLmunW_fHR4f5-kdncZbOlxxqKyk6ZAFQQEd2k,2088
|
|
38
38
|
icsDataValidation/utils/sql_util.py,sha256=0c-BInElSsRmXUedfLP_h9Wsiscv9aic7IIc5f15Uzo,396
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
icsdatavalidation-1.0.419.dist-info/METADATA,sha256=DFfV06xG1WzDcBigFRlfcKjEVrc1TV9ucLHpNPtDcfg,661
|
|
40
|
+
icsdatavalidation-1.0.419.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
41
|
+
icsdatavalidation-1.0.419.dist-info/top_level.txt,sha256=BqWUGJb4J7ZybpDMeuGHxEHGHwXXJEIURd9pBybHzTM,18
|
|
42
|
+
icsdatavalidation-1.0.419.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
icsDataValidation
|
examples/ics_data_validation.py
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
#########################################################################################
|
|
2
|
-
#########################################################################################
|
|
3
|
-
import os
|
|
4
|
-
|
|
5
|
-
def manual_execution_params():
|
|
6
|
-
|
|
7
|
-
# Manual execution: File location of the icsDataValidation configuration
|
|
8
|
-
os.environ["CONFIG_FOLDER_NAME"] = 'examples/'
|
|
9
|
-
os.environ["CONFIGURATION_FILE_NAME"] = 'ics_data_validation_config.json'
|
|
10
|
-
os.environ["MIGRATION_CONFIGURATION_FILE_NAME"] = 'migration_config.json'
|
|
11
|
-
|
|
12
|
-
# Manual execution: File path of the locally stored secrets
|
|
13
|
-
# Syntax: <parameter_name>="<value>" per row
|
|
14
|
-
os.environ["ENV_FILEPATH"] = ''
|
|
15
|
-
|
|
16
|
-
# Manual execution: Testset settings
|
|
17
|
-
os.environ["DATABASE_NAME"] = '' #
|
|
18
|
-
os.environ["SCHEMA_NAME"] = '' #
|
|
19
|
-
|
|
20
|
-
os.environ["TESTSET_FILE_NAMES"] = '' # for no testset define as ''
|
|
21
|
-
|
|
22
|
-
os.environ["OBJECT_TYPE_RESTRICTION"] = '' #'include_all', 'include_only_tables', 'include_only_views'
|
|
23
|
-
|
|
24
|
-
# Manual execution: Result settings
|
|
25
|
-
os.environ["UPLOAD_RESULT_TO_BLOB"] = '' #boolean: True or False
|
|
26
|
-
os.environ["UPLOAD_RESULT_TO_BUCKET"] = '' #boolean: True or False
|
|
27
|
-
os.environ["UPLOAD_RESULT_TO_RESULT_DATABASE"] = ''#boolean: True or False
|
|
28
|
-
|
|
29
|
-
# Manual execution: Pandas Dataframe Comparison restrictions -> -1 for no pandas-df comparison at all
|
|
30
|
-
os.environ["MAX_OBJECT_SIZE"] = str(-1) #-1
|
|
31
|
-
os.environ["MAX_ROW_NUMBER"] = str(-1) #-1
|
|
32
|
-
|
|
33
|
-
# Manual execution: Parallelization of comparison settings
|
|
34
|
-
os.environ["MAX_NUMBER_OF_THREADS"] = str(1) #1
|
|
35
|
-
|
|
36
|
-
# Manual execution: Group-By-Aggregation settings
|
|
37
|
-
os.environ["EXECUTE_GROUP_BY_COMPARISON"] = '' #boolean: True or False
|
|
38
|
-
os.environ["USE_GROUP_BY_COLUMNS"] = '' #boolean: True or False
|
|
39
|
-
os.environ["MIN_GROUP_BY_COUNT_DISTINCT"] = str(2) #2
|
|
40
|
-
os.environ["MAX_GROUP_BY_COUNT_DISTINCT"] = str(5) #5
|
|
41
|
-
os.environ["MAX_GROUP_BY_SIZE"] = str(100000000) #100000000
|
|
42
|
-
|
|
43
|
-
# Manual execution: Precision settings
|
|
44
|
-
os.environ["NUMERIC_SCALE"] = str(2)
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: icsDataValidation
|
|
3
|
-
Version: 1.0.378
|
|
4
|
-
Summary: ics data validation
|
|
5
|
-
Home-page: https://initions.com/
|
|
6
|
-
Author: initions
|
|
7
|
-
Author-email: ICSMC_EXT_PYPIORG@accenture.com
|
|
8
|
-
License: MIT
|
|
9
|
-
Requires-Dist: snowflake-connector-python[pandas] (==3.7.1)
|
|
10
|
-
Requires-Dist: python-dotenv (==0.20.0)
|
|
11
|
-
Requires-Dist: pyodbc
|
|
12
|
-
Requires-Dist: pyexasol (==0.24.0)
|
|
13
|
-
Requires-Dist: pandas (==2.2.2)
|
|
14
|
-
Requires-Dist: azure-storage-blob (==12.13.1)
|
|
15
|
-
Requires-Dist: teradatasql (==17.20.0.10)
|
|
16
|
-
Requires-Dist: boto3 (==1.26.154)
|
|
17
|
-
Requires-Dist: oracledb (==2.5.0)
|
|
18
|
-
Requires-Dist: databricks-sql-connector (==3.0.1)
|
|
19
|
-
Requires-Dist: databricks-sdk (==0.29.0)
|
|
20
|
-
Requires-Dist: numpy (==1.26.3)
|