SilverStreamingApplication 1.3__tar.gz → 1.5__tar.gz
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.
- silverstreamingapplication-1.5/PKG-INFO +7 -0
- {SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/SilverMerge.py +58 -16
- {SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/WorkflowBuilder.py +17 -3
- {SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/setup.py +2 -2
- silverstreamingapplication-1.5/silverstreamingapplication.egg-info/PKG-INFO +7 -0
- {SilverStreamingApplication-1.3/SilverStreamingApplication.egg-info → silverstreamingapplication-1.5/silverstreamingapplication.egg-info}/SOURCES.txt +5 -7
- SilverStreamingApplication-1.3/PKG-INFO +0 -12
- SilverStreamingApplication-1.3/SilverStreamingApplication.egg-info/PKG-INFO +0 -12
- SilverStreamingApplication-1.3/com/phida/main/__init__.py +0 -0
- SilverStreamingApplication-1.3/com/phida/tests/__init__.py +0 -0
- {SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/Maintenance.py +0 -0
- {SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/Operations.py +0 -0
- {SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/PartitionAnalyzer.py +0 -0
- {SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/PerfAnalyzer.py +0 -0
- {SilverStreamingApplication-1.3/com → silverstreamingapplication-1.5/com/phida/main}/__init__.py +0 -0
- {SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/logging.py +0 -0
- {SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/sparksession.py +0 -0
- {SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/utils.py +0 -0
- {SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/utilsDatabricksAPI.py +0 -0
- {SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/tests/OperationsTest.py +0 -0
- {SilverStreamingApplication-1.3/com/phida → silverstreamingapplication-1.5/com/phida/tests}/__init__.py +0 -0
- {SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/tests/main_test.py +0 -0
- {SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/tests/utils_test.py +0 -0
- {SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/setup.cfg +0 -0
- {SilverStreamingApplication-1.3/SilverStreamingApplication.egg-info → silverstreamingapplication-1.5/silverstreamingapplication.egg-info}/dependency_links.txt +0 -0
- {SilverStreamingApplication-1.3/SilverStreamingApplication.egg-info → silverstreamingapplication-1.5/silverstreamingapplication.egg-info}/top_level.txt +0 -0
{SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/SilverMerge.py
RENAMED
|
@@ -2,7 +2,7 @@ from com.phida.main.sparksession import spark, logger
|
|
|
2
2
|
from com.phida.main.Operations import tableExists, addDerivedColumns, createDeltaTable, alterDeltaTable, \
|
|
3
3
|
dropColumns, getDerivedColumnsList, schemaDiff, getKeyCols, buildJoinCondition, buildColumnsDict, hiveDDL, schemaDataTypeDiff
|
|
4
4
|
from com.phida.main.utils import pathExists, convertStrToList
|
|
5
|
-
from pyspark.sql.functions import row_number, col, broadcast,expr
|
|
5
|
+
from pyspark.sql.functions import row_number, col, broadcast,expr, max as spark_max
|
|
6
6
|
from pyspark.sql.window import Window
|
|
7
7
|
from delta.tables import DeltaTable
|
|
8
8
|
from pyspark.sql import DataFrame
|
|
@@ -25,6 +25,8 @@ class SilverMerge:
|
|
|
25
25
|
pruneColumn: String - Column for applying the prune filter in the merge ON condition clause \
|
|
26
26
|
(to improve performance of the merge)
|
|
27
27
|
cluster_table_path: String - Path to the cluster table
|
|
28
|
+
enable_delete_filter: String - Flag to enable/disable filtering of deleted records (default: 'N')
|
|
29
|
+
use_auto_loader: String - Flag to enable/disable use of autoloader for reading source table (default: 'N')
|
|
28
30
|
|
|
29
31
|
methods:
|
|
30
32
|
silverCleansing
|
|
@@ -36,12 +38,12 @@ class SilverMerge:
|
|
|
36
38
|
from com.phida.SilverMerge import SilverMerge
|
|
37
39
|
silverMergeObj = SilverMerge(srcDatabaseName, srcTableName, tgtDatabaseName, tgtTableName,
|
|
38
40
|
tgtCheckpoint, tgtTablePath, tgtPartitionColumns, derivedColExpr,
|
|
39
|
-
triggerOnce, dropColumnStr, pruneColumn, cluster_table_path)
|
|
41
|
+
triggerOnce, dropColumnStr, pruneColumn, cluster_table_path, enable_delete_filter, use_auto_loader)
|
|
40
42
|
|
|
41
43
|
"""
|
|
42
44
|
def __init__(self, srcDatabaseName, srcTableName, tgtDatabaseName, tgtTableName,
|
|
43
45
|
tgtCheckpoint, tgtTablePath, tgtPartitionColumns, derivedColExpr,
|
|
44
|
-
triggerOnce, dropColumnStr, pruneColumn, cluster_table_path):
|
|
46
|
+
triggerOnce, dropColumnStr, pruneColumn, cluster_table_path, enable_delete_filter, use_auto_loader):
|
|
45
47
|
"""
|
|
46
48
|
desc:
|
|
47
49
|
Initialize the required class variables
|
|
@@ -59,6 +61,8 @@ class SilverMerge:
|
|
|
59
61
|
dropColumnStr: String - Columns to be dropped from source table df
|
|
60
62
|
pruneColumn: String - Column to use for dynamic file pruning (future feature)
|
|
61
63
|
cluster_table_path: String - Path to the cluster table
|
|
64
|
+
enable_delete_filter: String - Flag to enable/disable filtering of deleted records (default: 'N')
|
|
65
|
+
use_auto_loader: String - Flag to enable/disable use of autoloader for reading source table (default: 'N')
|
|
62
66
|
"""
|
|
63
67
|
|
|
64
68
|
logger.info("phida_log: Initialising class variables")
|
|
@@ -75,6 +79,8 @@ class SilverMerge:
|
|
|
75
79
|
self.dropColumnStr = dropColumnStr
|
|
76
80
|
self.pruneColumn = pruneColumn
|
|
77
81
|
self.cluster_table_path = cluster_table_path
|
|
82
|
+
self.enable_delete_filter = enable_delete_filter.strip().upper() if enable_delete_filter else 'N'
|
|
83
|
+
self.use_auto_loader = use_auto_loader.strip().upper() if use_auto_loader and use_auto_loader.strip().upper() == 'Y' else 'N'
|
|
78
84
|
|
|
79
85
|
logger.info(f"phida_log: Check if source table {self.srcDatabaseName}.{self.srcTableName} exists")
|
|
80
86
|
|
|
@@ -84,7 +90,11 @@ class SilverMerge:
|
|
|
84
90
|
|
|
85
91
|
logger.info(f"phida_log: initialising derived class variables")
|
|
86
92
|
|
|
87
|
-
|
|
93
|
+
if self.use_auto_loader == 'N':
|
|
94
|
+
self.srcDF = spark.readStream.table(self.srcDatabaseName + "." + self.srcTableName)
|
|
95
|
+
elif self.use_auto_loader == 'Y':
|
|
96
|
+
src_table_path = spark.sql(f"DESCRIBE DETAIL {self.srcDatabaseName}.{self.srcTableName}").collect()[0]['location']
|
|
97
|
+
self.srcDF = spark.readStream.format("cloudFiles").option("cloudFiles.format", "parquet").option("cloudFiles.schemaLocation", src_table_path + "/_cloudfiles/_schemas").load(src_table_path).drop("_rescued_data")
|
|
88
98
|
|
|
89
99
|
self.keyCols = getKeyCols(self.srcDatabaseName, self.srcTableName)
|
|
90
100
|
|
|
@@ -204,7 +214,37 @@ class SilverMerge:
|
|
|
204
214
|
|
|
205
215
|
else:
|
|
206
216
|
logger.info(f"phida_log: There is no change in schema in silver")
|
|
207
|
-
|
|
217
|
+
|
|
218
|
+
def filter_deleted_records(self, microBatchOutputDF):
|
|
219
|
+
"""
|
|
220
|
+
Filters out records from microBatchOutputDF that have been marked as deleted in the Bronze table
|
|
221
|
+
within the last 4 hours based on hvr_integ_key.
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
if microBatchOutputDF.isEmpty():
|
|
225
|
+
return microBatchOutputDF
|
|
226
|
+
|
|
227
|
+
filtered_table_name = f"{self.srcDatabaseName}.{self.srcTableName}_filtered"
|
|
228
|
+
|
|
229
|
+
if not tableExists(self.srcDatabaseName, f"{self.srcTableName}_filtered"):
|
|
230
|
+
return microBatchOutputDF
|
|
231
|
+
|
|
232
|
+
delete_records = spark.read.table(filtered_table_name).filter(col("source_operation") == 0)
|
|
233
|
+
|
|
234
|
+
if delete_records.isEmpty():
|
|
235
|
+
return microBatchOutputDF
|
|
236
|
+
|
|
237
|
+
delete_keys_df = (delete_records.groupBy(self.keyColsList).agg(spark_max(col("hvr_integ_key")).alias("delete_hvr_integ_key")))
|
|
238
|
+
|
|
239
|
+
joined_df = microBatchOutputDF.join(broadcast(delete_keys_df), on=self.keyColsList, how="left")
|
|
240
|
+
|
|
241
|
+
filtered_df = (joined_df.filter(
|
|
242
|
+
(col("delete_hvr_integ_key").isNull()) |
|
|
243
|
+
(col("hvr_integ_key") >= col("delete_hvr_integ_key"))
|
|
244
|
+
)
|
|
245
|
+
.drop("delete_hvr_integ_key"))
|
|
246
|
+
|
|
247
|
+
return filtered_df
|
|
208
248
|
|
|
209
249
|
def preprocess_dataframe(self, df: DataFrame, parent_keys: list) -> DataFrame:
|
|
210
250
|
|
|
@@ -256,23 +296,25 @@ class SilverMerge:
|
|
|
256
296
|
microBatchOutputDF_8 = microBatchOutputDF.filter("source_operation in (0,1,2,3,8)")
|
|
257
297
|
tgtDeltaTable = DeltaTable.forName(spark, self.tgtDatabaseName + "." + self.tgtTableName)
|
|
258
298
|
|
|
259
|
-
if
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
tgtDeltaTable.
|
|
299
|
+
if self.cluster_table_path:
|
|
300
|
+
if not op_8_df.isEmpty():
|
|
301
|
+
table_details = DeltaTable.forName(spark, self.cluster_table_path)
|
|
302
|
+
table_details_df = table_details.toDF()
|
|
303
|
+
parent_keys = self.get_parent_keys(table_details_df, self.srcDatabaseName, self.srcTableName)
|
|
304
|
+
parent_key_conditions = " AND ".join([f"t.{col} = s.{col}" for col in parent_keys])
|
|
305
|
+
if not tgtDeltaTable.toDF().isEmpty():
|
|
306
|
+
tgtDeltaTable.alias("t").merge(microBatchOutputDF_8.alias("s"), parent_key_conditions) \
|
|
266
307
|
.whenMatchedDelete() \
|
|
267
308
|
.execute()
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
windowSpec = Window.partitionBy(self.keyColsList).orderBy(col("
|
|
271
|
-
col("hvr_integ_key").desc())
|
|
309
|
+
microBatchOutputDF = self.preprocess_dataframe(microBatchOutputDF_8, parent_keys)
|
|
310
|
+
|
|
311
|
+
windowSpec = Window.partitionBy(self.keyColsList).orderBy(col("hvr_integ_key").desc())
|
|
272
312
|
|
|
273
313
|
microBatchOutputDF = microBatchOutputDF.withColumn("latest_record", row_number().over(windowSpec)).filter(
|
|
274
314
|
"latest_record == 1").drop("latest_record")
|
|
275
315
|
|
|
316
|
+
if self.enable_delete_filter == 'Y':
|
|
317
|
+
microBatchOutputDF = self.filter_deleted_records(microBatchOutputDF)
|
|
276
318
|
|
|
277
319
|
tgtDeltaTable.alias("t").merge(microBatchOutputDF.alias("s"), self.condition) \
|
|
278
320
|
.whenMatchedDelete("s.source_operation in (0,3)") \
|
{SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/WorkflowBuilder.py
RENAMED
|
@@ -72,7 +72,7 @@ class WorkflowBuilder:
|
|
|
72
72
|
@staticmethod
|
|
73
73
|
def createTask(taskKey, jobClusterKey, notebookPath, srcDatabaseName, srcTableName, tgtDatabaseName, tgtTableName,
|
|
74
74
|
tgtCheckpoint, tgtTablePath, tgtPartitionColumns, derivedColExpr, triggerOnce, dropColumnStr,
|
|
75
|
-
pruneColumn,cluster_table_path,
|
|
75
|
+
pruneColumn, cluster_table_path, enable_delete_filter, enable_autoloader, library):
|
|
76
76
|
"""
|
|
77
77
|
desc:
|
|
78
78
|
A method for creating the dict/json for a single task
|
|
@@ -94,6 +94,8 @@ class WorkflowBuilder:
|
|
|
94
94
|
pruneColumn: String - Column for applying the prune filter in the merge ON condition clause \
|
|
95
95
|
(to improve performance of the merge)
|
|
96
96
|
cluster_table_path: String - The path of the table in the cluster
|
|
97
|
+
enable_delete_filter: String - Flag to enable/disable filtering of deleted records (default: 'N')
|
|
98
|
+
enable_autoloader: String - Flag to enable/disable autoloader (default: 'N')
|
|
97
99
|
pythonWhlPath: String - Path of the python wheel file
|
|
98
100
|
library: String - Library to be installed for the job (with version number)
|
|
99
101
|
|
|
@@ -133,7 +135,9 @@ class WorkflowBuilder:
|
|
|
133
135
|
"trigger_once": triggerOnce,
|
|
134
136
|
"prune_column": pruneColumn,
|
|
135
137
|
"drop_column_list": dropColumnStr,
|
|
136
|
-
"cluster_table_path": cluster_table_path
|
|
138
|
+
"cluster_table_path": cluster_table_path,
|
|
139
|
+
"enable_delete_filter": str(enable_delete_filter),
|
|
140
|
+
"enable_autoloader": enable_autoloader
|
|
137
141
|
}
|
|
138
142
|
},
|
|
139
143
|
"timeout_seconds": timeout_seconds,
|
|
@@ -334,11 +338,21 @@ class WorkflowBuilder:
|
|
|
334
338
|
cluster_table_path = task['cluster_table_path']
|
|
335
339
|
except:
|
|
336
340
|
cluster_table_path = ""
|
|
341
|
+
|
|
342
|
+
try:
|
|
343
|
+
enable_delete_filter = task['enable_delete_filter']
|
|
344
|
+
except:
|
|
345
|
+
enable_delete_filter = ""
|
|
346
|
+
|
|
347
|
+
try:
|
|
348
|
+
enable_autoloader = task['enable_autoloader']
|
|
349
|
+
except:
|
|
350
|
+
enable_autoloader = ""
|
|
337
351
|
|
|
338
352
|
taskTemp = self.createTask(taskKey, jobClusterKey, notebookPath, srcDatabaseName, srcTableName,
|
|
339
353
|
tgtDatabaseName, tgtTableName, tgtCheckpoint, tgtTablePath,
|
|
340
354
|
tgtPartitionColumns, derivedColExpr, triggerOnce, dropColumnStr,
|
|
341
|
-
pruneColumn,cluster_table_path,
|
|
355
|
+
pruneColumn, cluster_table_path, enable_delete_filter, enable_autoloader, self.library)
|
|
342
356
|
|
|
343
357
|
tasks.append(taskTemp)
|
|
344
358
|
if jobId is None:
|
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
setup.py
|
|
2
|
-
SilverStreamingApplication.egg-info/PKG-INFO
|
|
3
|
-
SilverStreamingApplication.egg-info/SOURCES.txt
|
|
4
|
-
SilverStreamingApplication.egg-info/dependency_links.txt
|
|
5
|
-
SilverStreamingApplication.egg-info/top_level.txt
|
|
6
|
-
com/__init__.py
|
|
7
|
-
com/phida/__init__.py
|
|
8
2
|
com/phida/main/Maintenance.py
|
|
9
3
|
com/phida/main/Operations.py
|
|
10
4
|
com/phida/main/PartitionAnalyzer.py
|
|
@@ -19,4 +13,8 @@ com/phida/main/utilsDatabricksAPI.py
|
|
|
19
13
|
com/phida/tests/OperationsTest.py
|
|
20
14
|
com/phida/tests/__init__.py
|
|
21
15
|
com/phida/tests/main_test.py
|
|
22
|
-
com/phida/tests/utils_test.py
|
|
16
|
+
com/phida/tests/utils_test.py
|
|
17
|
+
silverstreamingapplication.egg-info/PKG-INFO
|
|
18
|
+
silverstreamingapplication.egg-info/SOURCES.txt
|
|
19
|
+
silverstreamingapplication.egg-info/dependency_links.txt
|
|
20
|
+
silverstreamingapplication.egg-info/top_level.txt
|
|
File without changes
|
|
File without changes
|
{SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/Maintenance.py
RENAMED
|
File without changes
|
{SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/Operations.py
RENAMED
|
File without changes
|
|
File without changes
|
{SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/PerfAnalyzer.py
RENAMED
|
File without changes
|
{SilverStreamingApplication-1.3/com → silverstreamingapplication-1.5/com/phida/main}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/main/sparksession.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/tests/OperationsTest.py
RENAMED
|
File without changes
|
|
File without changes
|
{SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/tests/main_test.py
RENAMED
|
File without changes
|
{SilverStreamingApplication-1.3 → silverstreamingapplication-1.5}/com/phida/tests/utils_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|