databricks-modules-vy 1.2__tar.gz → 1.2.2__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 (23) hide show
  1. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/PKG-INFO +1 -1
  2. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy/sharepoint.py +21 -0
  3. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy/unity_catalog.py +33 -5
  4. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy.egg-info/PKG-INFO +1 -1
  5. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/pyproject.toml +1 -1
  6. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/LICENSE +0 -0
  7. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy/__init__.py +0 -0
  8. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy/data_product.py +0 -0
  9. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy/data_quality_tests.py +0 -0
  10. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy/dataframe.py +0 -0
  11. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy/extend_class.py +0 -0
  12. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy/glue.py +0 -0
  13. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy/logging.py +0 -0
  14. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy/oracle.py +0 -0
  15. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy/qlik.py +0 -0
  16. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy/s3.py +0 -0
  17. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy/service_platform.py +0 -0
  18. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy/snaplogic.py +0 -0
  19. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy/styringsinfo_postgres.py +0 -0
  20. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy.egg-info/SOURCES.txt +0 -0
  21. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy.egg-info/dependency_links.txt +0 -0
  22. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/databricks_modules_vy.egg-info/top_level.txt +0 -0
  23. {databricks_modules_vy-1.2 → databricks_modules_vy-1.2.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: databricks_modules_vy
3
- Version: 1.2
3
+ Version: 1.2.2
4
4
  Summary: Databricks modules for Vy
5
5
  Author-email: Sindre Kjetså <sindre.kjetsa@vy.no>
6
6
  Project-URL: Homepage, https://github.com/nsbno/
@@ -283,6 +283,27 @@ def df_from_sharepoint_csv_utf8(
283
283
  return df
284
284
 
285
285
 
286
+ def df_from_sharepoint_excel(item_path, site_name="VyMasterdata", **kwargs) -> DataFrame:
287
+ """Gets the bytes from an excel file in sharepoint and converts it to a spark dataframe.
288
+
289
+ Requires the 'openpyxl' package, install it with '%pip install openpyxl'.
290
+
291
+ Args:
292
+ item_path (str) : path relative to the site the file is located. Initiate the path with '/'
293
+ site_name (str) : name of site to fetch the file from
294
+ **kwargs : additional keyword arguments passed directly to pd.read_excel
295
+ Returns:
296
+ (spark.DataFrame) dataframe of the excel sheet
297
+ """
298
+ file_bytesio = _get_file_bytes_from_sharepoint(item_path, site_name)
299
+ dp = pd.read_excel(io=file_bytesio, **kwargs)
300
+ dp = dp.replace([np.nan], [None])
301
+
302
+ df = spark.createDataFrame(dp)
303
+
304
+ return df
305
+
306
+
286
307
  # # Functions for traversing and extracting files and folders from a site # #
287
308
  def get_files_in_folder(relative_path_to_folder, site_name="VyMasterdata"):
288
309
  """
@@ -9,6 +9,24 @@ import re
9
9
  spark = SparkSession.builder.appName("module").getOrCreate()
10
10
 
11
11
 
12
+ def _sql_string_literal(value: object) -> str:
13
+ """
14
+ Converts a Python value into a safe SQL string literal.
15
+
16
+ Escapes single quotes and removes null bytes that can break SQL parsing.
17
+ """
18
+ text = "" if value is None else str(value)
19
+ text = text.replace("\x00", "").replace("'", "''")
20
+ return f"'{text}'"
21
+
22
+
23
+ def _quote_identifier(identifier: str) -> str:
24
+ """
25
+ Quotes a SQL identifier using backticks and escapes embedded backticks.
26
+ """
27
+ return f"`{identifier.replace('`', '``')}`"
28
+
29
+
12
30
  def write_to_uc(
13
31
  df: DataFrame,
14
32
  target: str,
@@ -81,7 +99,9 @@ def write_to_uc(
81
99
 
82
100
  if table_description:
83
101
  lp("Commenting table ...")
84
- spark.sql(f"COMMENT ON TABLE {target} IS '{table_description}'")
102
+ spark.sql(
103
+ f"COMMENT ON TABLE {target} IS {_sql_string_literal(table_description)}"
104
+ )
85
105
 
86
106
  if comments:
87
107
  if autoformat_columns:
@@ -207,7 +227,9 @@ def upsert_to_uc(
207
227
 
208
228
  if table_description:
209
229
  lp("Commenting table ...")
210
- spark.sql(f"COMMENT ON TABLE {target} IS '{table_description}'")
230
+ spark.sql(
231
+ f"COMMENT ON TABLE {target} IS {_sql_string_literal(table_description)}"
232
+ )
211
233
 
212
234
  if comments:
213
235
  if autoformat_columns:
@@ -308,7 +330,9 @@ def autoloader_batch_to_uc(
308
330
 
309
331
  if table_description:
310
332
  lp("Commenting table ...")
311
- spark.sql(f"COMMENT ON TABLE {target} IS '{table_description}'")
333
+ spark.sql(
334
+ f"COMMENT ON TABLE {target} IS {_sql_string_literal(table_description)}"
335
+ )
312
336
 
313
337
  if comments:
314
338
  if autoformat_columns:
@@ -455,12 +479,16 @@ def _apply_comments(
455
479
  if overwrite_schema or not current_comments:
456
480
  # If schema is overwritten or there are no comments currently, reapply all comments
457
481
  for col, comment in comments.items():
458
- spark.sql(f"ALTER TABLE {target} CHANGE {col} COMMENT '{comment}'")
482
+ spark.sql(
483
+ f"ALTER TABLE {target} CHANGE {_quote_identifier(col)} COMMENT {_sql_string_literal(comment)}"
484
+ )
459
485
  else:
460
486
  # If schema is not overwritten, only apply comments that have changed or are new
461
487
  for col, comment in comments.items():
462
488
  if col not in current_comments or comment != current_comments[col]:
463
- spark.sql(f"ALTER TABLE {target} CHANGE {col} COMMENT '{comment}'")
489
+ spark.sql(
490
+ f"ALTER TABLE {target} CHANGE {_quote_identifier(col)} COMMENT {_sql_string_literal(comment)}"
491
+ )
464
492
 
465
493
 
466
494
  def _format_column_name(column_name: str) -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: databricks_modules_vy
3
- Version: 1.2
3
+ Version: 1.2.2
4
4
  Summary: Databricks modules for Vy
5
5
  Author-email: Sindre Kjetså <sindre.kjetsa@vy.no>
6
6
  Project-URL: Homepage, https://github.com/nsbno/
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "databricks_modules_vy"
3
- version = "1.2"
3
+ version = "1.2.2"
4
4
  authors = [
5
5
  { name="Sindre Kjetså", email="sindre.kjetsa@vy.no" },
6
6
  ]