SilverStreamingApplication 1.2__tar.gz → 1.3__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.
Files changed (24) hide show
  1. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/PKG-INFO +1 -1
  2. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/SilverStreamingApplication.egg-info/PKG-INFO +1 -1
  3. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/main/SilverMerge.py +50 -8
  4. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/main/WorkflowBuilder.py +12 -4
  5. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/setup.py +1 -1
  6. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/SilverStreamingApplication.egg-info/SOURCES.txt +0 -0
  7. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/SilverStreamingApplication.egg-info/dependency_links.txt +0 -0
  8. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/SilverStreamingApplication.egg-info/top_level.txt +0 -0
  9. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/__init__.py +0 -0
  10. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/__init__.py +0 -0
  11. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/main/Maintenance.py +0 -0
  12. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/main/Operations.py +0 -0
  13. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/main/PartitionAnalyzer.py +0 -0
  14. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/main/PerfAnalyzer.py +0 -0
  15. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/main/__init__.py +0 -0
  16. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/main/logging.py +0 -0
  17. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/main/sparksession.py +0 -0
  18. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/main/utils.py +0 -0
  19. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/main/utilsDatabricksAPI.py +0 -0
  20. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/tests/OperationsTest.py +0 -0
  21. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/tests/__init__.py +0 -0
  22. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/tests/main_test.py +0 -0
  23. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/com/phida/tests/utils_test.py +0 -0
  24. {SilverStreamingApplication-1.2 → SilverStreamingApplication-1.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: SilverStreamingApplication
3
- Version: 1.2
3
+ Version: 1.3
4
4
  Summary: initial version
5
5
  Home-page: UNKNOWN
6
6
  Author:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: SilverStreamingApplication
3
- Version: 1.2
3
+ Version: 1.3
4
4
  Summary: initial version
5
5
  Home-page: UNKNOWN
6
6
  Author:
@@ -2,10 +2,10 @@ 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
5
+ from pyspark.sql.functions import row_number, col, broadcast,expr
6
6
  from pyspark.sql.window import Window
7
7
  from delta.tables import DeltaTable
8
-
8
+ from pyspark.sql import DataFrame
9
9
 
10
10
  class SilverMerge:
11
11
  """
@@ -24,6 +24,7 @@ class SilverMerge:
24
24
  dropColumnStr: String - Columns to be dropped from source table df
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
+ cluster_table_path: String - Path to the cluster table
27
28
 
28
29
  methods:
29
30
  silverCleansing
@@ -35,12 +36,12 @@ class SilverMerge:
35
36
  from com.phida.SilverMerge import SilverMerge
36
37
  silverMergeObj = SilverMerge(srcDatabaseName, srcTableName, tgtDatabaseName, tgtTableName,
37
38
  tgtCheckpoint, tgtTablePath, tgtPartitionColumns, derivedColExpr,
38
- triggerOnce, dropColumnStr, pruneColumn)
39
+ triggerOnce, dropColumnStr, pruneColumn, cluster_table_path)
39
40
 
40
41
  """
41
42
  def __init__(self, srcDatabaseName, srcTableName, tgtDatabaseName, tgtTableName,
42
43
  tgtCheckpoint, tgtTablePath, tgtPartitionColumns, derivedColExpr,
43
- triggerOnce, dropColumnStr, pruneColumn):
44
+ triggerOnce, dropColumnStr, pruneColumn, cluster_table_path):
44
45
  """
45
46
  desc:
46
47
  Initialize the required class variables
@@ -57,7 +58,7 @@ class SilverMerge:
57
58
  triggerOnce: String - Whether continuous streaming or just once
58
59
  dropColumnStr: String - Columns to be dropped from source table df
59
60
  pruneColumn: String - Column to use for dynamic file pruning (future feature)
60
-
61
+ cluster_table_path: String - Path to the cluster table
61
62
  """
62
63
 
63
64
  logger.info("phida_log: Initialising class variables")
@@ -73,6 +74,7 @@ class SilverMerge:
73
74
  self.triggerOnce = triggerOnce
74
75
  self.dropColumnStr = dropColumnStr
75
76
  self.pruneColumn = pruneColumn
77
+ self.cluster_table_path = cluster_table_path
76
78
 
77
79
  logger.info(f"phida_log: Check if source table {self.srcDatabaseName}.{self.srcTableName} exists")
78
80
 
@@ -202,6 +204,34 @@ class SilverMerge:
202
204
 
203
205
  else:
204
206
  logger.info(f"phida_log: There is no change in schema in silver")
207
+
208
+
209
+ def preprocess_dataframe(self, df: DataFrame, parent_keys: list) -> DataFrame:
210
+
211
+ """Removes rows where all or any 'source_operation' values for a group are 8."""
212
+
213
+ grouped_df = df.groupBy(parent_keys).agg(
214
+ expr("bool_and(source_operation = 8)").alias("all_8"),
215
+ expr("bool_or(source_operation = 8)").alias("any_8")
216
+ )
217
+
218
+ return df.join(grouped_df, on=parent_keys, how="left").filter("NOT (all_8 OR any_8)")
219
+
220
+
221
+ def get_parent_keys(self, df: DataFrame, kernel_value: str, unpack_table_value: str) -> list:
222
+
223
+ """Get the parent keys for the given kernel and unpack_table values"""
224
+
225
+ filtered_df = df.filter(
226
+ (col("kernel") == kernel_value) & (col("unpack_table") == unpack_table_value)
227
+ )
228
+ row = filtered_df.select("key_columns_for_pack_table", "key_columns_for_unpack_table").first()
229
+ pack_keys = set(row["key_columns_for_pack_table"].split(',')) if row["key_columns_for_pack_table"] else set()
230
+ unpack_keys = set(row["key_columns_for_unpack_table"].split(',')) if row["key_columns_for_unpack_table"] else set()
231
+ parent_keys = list(pack_keys & unpack_keys)
232
+ return parent_keys
233
+
234
+
205
235
 
206
236
  def upsertToDelta(self, microBatchOutputDF, batchId):
207
237
  """
@@ -221,16 +251,28 @@ class SilverMerge:
221
251
  tip:
222
252
  N/A
223
253
  """
224
-
254
+ op_8_df = microBatchOutputDF.filter("source_operation = 8")
225
255
  microBatchOutputDF = microBatchOutputDF.filter("source_operation in (0,1,2,3)")
226
-
256
+ microBatchOutputDF_8 = microBatchOutputDF.filter("source_operation in (0,1,2,3,8)")
257
+ tgtDeltaTable = DeltaTable.forName(spark, self.tgtDatabaseName + "." + self.tgtTableName)
258
+
259
+ if not op_8_df.isEmpty():
260
+ table_details = DeltaTable.forName(spark,self.cluster_table_path)
261
+ table_details_df = table_details.toDF()
262
+ parent_keys = self.get_parent_keys(table_details_df, self.srcDatabaseName, self.srcTableName)
263
+ parent_key_conditions = " AND ".join([f"t.{col} = s.{col}" for col in parent_keys])
264
+ if not tgtDeltaTable.toDF().isEmpty():
265
+ tgtDeltaTable.alias("t").merge(microBatchOutputDF_8.alias("s"), parent_key_conditions) \
266
+ .whenMatchedDelete() \
267
+ .execute()
268
+ microBatchOutputDF = self.preprocess_dataframe(microBatchOutputDF_8, parent_keys)
269
+
227
270
  windowSpec = Window.partitionBy(self.keyColsList).orderBy(col("src_commit_time").desc(),
228
271
  col("hvr_integ_key").desc())
229
272
 
230
273
  microBatchOutputDF = microBatchOutputDF.withColumn("latest_record", row_number().over(windowSpec)).filter(
231
274
  "latest_record == 1").drop("latest_record")
232
275
 
233
- tgtDeltaTable = DeltaTable.forName(spark, self.tgtDatabaseName + "." + self.tgtTableName)
234
276
 
235
277
  tgtDeltaTable.alias("t").merge(microBatchOutputDF.alias("s"), self.condition) \
236
278
  .whenMatchedDelete("s.source_operation in (0,3)") \
@@ -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, pythonWhlPath, library):
75
+ pruneColumn,cluster_table_path, pythonWhlPath, library):
76
76
  """
77
77
  desc:
78
78
  A method for creating the dict/json for a single task
@@ -93,6 +93,8 @@ class WorkflowBuilder:
93
93
  dropColumnStr: String - Columns to be dropped from source table df
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
+ cluster_table_path: String - The path of the table in the cluster
97
+ pythonWhlPath: String - Path of the python wheel file
96
98
  library: String - Library to be installed for the job (with version number)
97
99
 
98
100
  return:
@@ -130,7 +132,8 @@ class WorkflowBuilder:
130
132
  "derived_col_expr": derivedColExpr,
131
133
  "trigger_once": triggerOnce,
132
134
  "prune_column": pruneColumn,
133
- "drop_column_list": dropColumnStr
135
+ "drop_column_list": dropColumnStr,
136
+ "cluster_table_path": cluster_table_path
134
137
  }
135
138
  },
136
139
  "timeout_seconds": timeout_seconds,
@@ -311,7 +314,7 @@ class WorkflowBuilder:
311
314
  tgtTablePath = task['tgt_table_path']
312
315
  triggerOnce = task['trigger_once']
313
316
  dropColumnStr = task['drop_column_list']
314
-
317
+
315
318
  try:
316
319
  tgtPartitionColumns = task['tgt_partition_columns']
317
320
  except:
@@ -326,11 +329,16 @@ class WorkflowBuilder:
326
329
  pruneColumn = task['prune_column']
327
330
  except:
328
331
  pruneColumn = ""
332
+
333
+ try:
334
+ cluster_table_path = task['cluster_table_path']
335
+ except:
336
+ cluster_table_path = ""
329
337
 
330
338
  taskTemp = self.createTask(taskKey, jobClusterKey, notebookPath, srcDatabaseName, srcTableName,
331
339
  tgtDatabaseName, tgtTableName, tgtCheckpoint, tgtTablePath,
332
340
  tgtPartitionColumns, derivedColExpr, triggerOnce, dropColumnStr,
333
- pruneColumn, "", self.library)
341
+ pruneColumn,cluster_table_path, "", self.library)
334
342
 
335
343
  tasks.append(taskTemp)
336
344
  if jobId is None:
@@ -2,7 +2,7 @@ from setuptools import setup
2
2
 
3
3
  setup(
4
4
  name='SilverStreamingApplication',
5
- version='1.2',
5
+ version='1.3',
6
6
  packages=['com.phida.main', 'com.phida.tests'],
7
7
  url='',
8
8
  license='',