semantic-link-labs 0.7.2__py3-none-any.whl → 0.7.3__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.

Potentially problematic release.


This version of semantic-link-labs might be problematic. Click here for more details.

Files changed (34) hide show
  1. {semantic_link_labs-0.7.2.dist-info → semantic_link_labs-0.7.3.dist-info}/METADATA +3 -2
  2. {semantic_link_labs-0.7.2.dist-info → semantic_link_labs-0.7.3.dist-info}/RECORD +34 -27
  3. {semantic_link_labs-0.7.2.dist-info → semantic_link_labs-0.7.3.dist-info}/WHEEL +1 -1
  4. sempy_labs/__init__.py +60 -3
  5. sempy_labs/_bpa_translation/_translations_sv-SE.po +914 -0
  6. sempy_labs/_clear_cache.py +298 -3
  7. sempy_labs/_dataflows.py +130 -0
  8. sempy_labs/_deployment_pipelines.py +171 -0
  9. sempy_labs/_generate_semantic_model.py +148 -27
  10. sempy_labs/_git.py +380 -0
  11. sempy_labs/_helper_functions.py +57 -0
  12. sempy_labs/_list_functions.py +144 -121
  13. sempy_labs/_model_bpa.py +85 -83
  14. sempy_labs/_model_bpa_bulk.py +3 -1
  15. sempy_labs/_model_bpa_rules.py +788 -800
  16. sempy_labs/_sql.py +96 -0
  17. sempy_labs/_translations.py +0 -1
  18. sempy_labs/_workspace_identity.py +66 -0
  19. sempy_labs/directlake/__init__.py +2 -0
  20. sempy_labs/directlake/_directlake_schema_compare.py +1 -2
  21. sempy_labs/directlake/_dl_helper.py +4 -7
  22. sempy_labs/directlake/_generate_shared_expression.py +85 -0
  23. sempy_labs/directlake/_show_unsupported_directlake_objects.py +1 -2
  24. sempy_labs/lakehouse/_get_lakehouse_tables.py +7 -3
  25. sempy_labs/migration/_migrate_calctables_to_lakehouse.py +5 -0
  26. sempy_labs/migration/_migrate_calctables_to_semantic_model.py +5 -0
  27. sempy_labs/migration/_migrate_model_objects_to_semantic_model.py +6 -2
  28. sempy_labs/migration/_migrate_tables_columns_to_semantic_model.py +6 -5
  29. sempy_labs/migration/_migration_validation.py +6 -0
  30. sempy_labs/report/_report_functions.py +21 -42
  31. sempy_labs/report/_report_rebind.py +5 -0
  32. sempy_labs/tom/_model.py +91 -52
  33. {semantic_link_labs-0.7.2.dist-info → semantic_link_labs-0.7.3.dist-info}/LICENSE +0 -0
  34. {semantic_link_labs-0.7.2.dist-info → semantic_link_labs-0.7.3.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,6 @@
1
1
  import sempy.fabric as fabric
2
2
  from sempy_labs._helper_functions import (
3
3
  resolve_workspace_name_and_id,
4
- resolve_lakehouse_name,
5
4
  create_relationship_name,
6
5
  resolve_lakehouse_id,
7
6
  resolve_dataset_id,
@@ -86,7 +85,9 @@ def get_object_level_security(
86
85
  return df
87
86
 
88
87
 
89
- def list_tables(dataset: str, workspace: Optional[str] = None) -> pd.DataFrame:
88
+ def list_tables(
89
+ dataset: str, workspace: Optional[str] = None, extended: Optional[bool] = False
90
+ ) -> pd.DataFrame:
90
91
  """
91
92
  Shows a semantic model's tables and their properties.
92
93
 
@@ -98,6 +99,8 @@ def list_tables(dataset: str, workspace: Optional[str] = None) -> pd.DataFrame:
98
99
  The Fabric workspace name.
99
100
  Defaults to None which resolves to the workspace of the attached lakehouse
100
101
  or if no lakehouse attached, resolves to the workspace of the notebook.
102
+ extended : bool, default=False
103
+ Adds additional columns including Vertipaq statistics.
101
104
 
102
105
  Returns
103
106
  -------
@@ -105,18 +108,136 @@ def list_tables(dataset: str, workspace: Optional[str] = None) -> pd.DataFrame:
105
108
  A pandas dataframe showing the semantic model's tables and their properties.
106
109
  """
107
110
 
111
+ from sempy_labs.tom import connect_semantic_model
112
+
108
113
  workspace = fabric.resolve_workspace_name(workspace)
109
114
 
110
- df = fabric.list_tables(
111
- dataset=dataset,
112
- workspace=workspace,
113
- additional_xmla_properties=["RefreshPolicy", "RefreshPolicy.SourceExpression"],
115
+ df = pd.DataFrame(
116
+ columns=[
117
+ "Name",
118
+ "Description",
119
+ "Hidden",
120
+ "Data Category",
121
+ "Type",
122
+ "Refresh Policy",
123
+ "Source Expression",
124
+ ]
114
125
  )
115
126
 
116
- df["Refresh Policy"] = df["Refresh Policy"].notna()
117
- df.rename(
118
- columns={"Refresh Policy Source Expression": "Source Expression"}, inplace=True
119
- )
127
+ with connect_semantic_model(
128
+ dataset=dataset, workspace=workspace, readonly=True
129
+ ) as tom:
130
+ if extended:
131
+ dict_df = fabric.evaluate_dax(
132
+ dataset=dataset,
133
+ workspace=workspace,
134
+ dax_string="""
135
+ EVALUATE SELECTCOLUMNS(FILTER(INFO.STORAGETABLECOLUMNS(), [COLUMN_TYPE] = "BASIC_DATA"),[DIMENSION_NAME],[DICTIONARY_SIZE])
136
+ """,
137
+ )
138
+ dict_sum = dict_df.groupby("[DIMENSION_NAME]")["[DICTIONARY_SIZE]"].sum()
139
+ data = fabric.evaluate_dax(
140
+ dataset=dataset,
141
+ workspace=workspace,
142
+ dax_string="""EVALUATE SELECTCOLUMNS(INFO.STORAGETABLECOLUMNSEGMENTS(),[TABLE_ID],[DIMENSION_NAME],[USED_SIZE])""",
143
+ )
144
+ data_sum = (
145
+ data[
146
+ ~data["[TABLE_ID]"].str.startswith("R$")
147
+ & ~data["[TABLE_ID]"].str.startswith("U$")
148
+ & ~data["[TABLE_ID]"].str.startswith("H$")
149
+ ]
150
+ .groupby("[DIMENSION_NAME]")["[USED_SIZE]"]
151
+ .sum()
152
+ )
153
+ hier_sum = (
154
+ data[data["[TABLE_ID]"].str.startswith("H$")]
155
+ .groupby("[DIMENSION_NAME]")["[USED_SIZE]"]
156
+ .sum()
157
+ )
158
+ rel_sum = (
159
+ data[data["[TABLE_ID]"].str.startswith("R$")]
160
+ .groupby("[DIMENSION_NAME]")["[USED_SIZE]"]
161
+ .sum()
162
+ )
163
+ uh_sum = (
164
+ data[data["[TABLE_ID]"].str.startswith("U$")]
165
+ .groupby("[DIMENSION_NAME]")["[USED_SIZE]"]
166
+ .sum()
167
+ )
168
+ rc = fabric.evaluate_dax(
169
+ dataset=dataset,
170
+ workspace=workspace,
171
+ dax_string="""
172
+ SELECT [DIMENSION_NAME],[DIMENSION_CARDINALITY] FROM $SYSTEM.MDSCHEMA_DIMENSIONS
173
+ """,
174
+ )
175
+
176
+ rows = []
177
+ for t in tom.model.Tables:
178
+ t_name = t.Name
179
+ t_type = (
180
+ "Calculation Group"
181
+ if t.CalculationGroup
182
+ else (
183
+ "Calculated Table"
184
+ if tom.is_calculated_table(table_name=t.Name)
185
+ else "Table"
186
+ )
187
+ )
188
+ ref = bool(t.RefreshPolicy)
189
+ ref_se = t.RefreshPolicy.SourceExpression if ref else None
190
+
191
+ new_data = {
192
+ "Name": t_name,
193
+ "Description": t.Description,
194
+ "Hidden": t.IsHidden,
195
+ "Data Category": t.DataCategory,
196
+ "Type": t_type,
197
+ "Refresh Policy": ref,
198
+ "Source Expression": ref_se,
199
+ }
200
+
201
+ if extended:
202
+ dict_size = dict_sum.get(t_name, 0)
203
+ data_size = data_sum.get(t_name, 0)
204
+ h_size = hier_sum.get(t_name, 0)
205
+ r_size = rel_sum.get(t_name, 0)
206
+ u_size = uh_sum.get(t_name, 0)
207
+ total_size = data_size + dict_size + h_size + r_size + u_size
208
+
209
+ new_data.update(
210
+ {
211
+ "Row Count": (
212
+ rc[rc["DIMENSION_NAME"] == t_name][
213
+ "DIMENSION_CARDINALITY"
214
+ ].iloc[0]
215
+ if not rc.empty
216
+ else 0
217
+ ),
218
+ "Total Size": total_size,
219
+ "Dictionary Size": dict_size,
220
+ "Data Size": data_size,
221
+ "Hierarchy Size": h_size,
222
+ "Relationship Size": r_size,
223
+ "User Hierarchy Size": u_size,
224
+ }
225
+ )
226
+
227
+ rows.append(new_data)
228
+
229
+ int_cols = [
230
+ "Row Count",
231
+ "Total Size",
232
+ "Dictionary Size",
233
+ "Data Size",
234
+ "Hierarchy Size",
235
+ "Relationship Size",
236
+ "User Hierarchy Size",
237
+ ]
238
+ df[int_cols] = df[int_cols].astype(int)
239
+
240
+ df = pd.DataFrame(rows)
120
241
 
121
242
  return df
122
243
 
@@ -880,14 +1001,10 @@ def list_eventstreams(workspace: Optional[str] = None) -> pd.DataFrame:
880
1001
 
881
1002
  for r in responses:
882
1003
  for v in r.get("value", []):
883
- model_id = v.get("id")
884
- modelName = v.get("displayName")
885
- desc = v.get("description")
886
-
887
1004
  new_data = {
888
- "Eventstream Name": modelName,
889
- "Eventstream ID": model_id,
890
- "Description": desc,
1005
+ "Eventstream Name": v.get("displayName"),
1006
+ "Eventstream ID": v.get("id"),
1007
+ "Description": v.get("description"),
891
1008
  }
892
1009
  df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
893
1010
 
@@ -1030,10 +1147,6 @@ def create_warehouse(
1030
1147
  The Fabric workspace name.
1031
1148
  Defaults to None which resolves to the workspace of the attached lakehouse
1032
1149
  or if no lakehouse attached, resolves to the workspace of the notebook.
1033
-
1034
- Returns
1035
- -------
1036
-
1037
1150
  """
1038
1151
 
1039
1152
  (workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
@@ -1045,11 +1158,11 @@ def create_warehouse(
1045
1158
 
1046
1159
  client = fabric.FabricRestClient()
1047
1160
  response = client.post(
1048
- f"/v1/workspaces/{workspace_id}/warehouses/", json=request_body, lro_wait=True
1161
+ f"/v1/workspaces/{workspace_id}/warehouses/", json=request_body
1049
1162
  )
1050
1163
 
1051
- if response.status_code != 200:
1052
- raise FabricHTTPException(response)
1164
+ lro(client, response, status_codes=[201, 202])
1165
+
1053
1166
  print(
1054
1167
  f"{icons.green_dot} The '{warehouse}' warehouse has been created within the '{workspace}' workspace."
1055
1168
  )
@@ -1216,44 +1329,6 @@ def list_relationships(
1216
1329
  return dfR
1217
1330
 
1218
1331
 
1219
- def list_dataflow_storage_accounts() -> pd.DataFrame:
1220
- """
1221
- Shows the accessible dataflow storage accounts.
1222
-
1223
- Parameters
1224
- ----------
1225
-
1226
- Returns
1227
- -------
1228
- pandas.DataFrame
1229
- A pandas dataframe showing the accessible dataflow storage accounts.
1230
- """
1231
-
1232
- df = pd.DataFrame(
1233
- columns=[
1234
- "Dataflow Storage Account ID",
1235
- "Dataflow Storage Account Name",
1236
- "Enabled",
1237
- ]
1238
- )
1239
- client = fabric.PowerBIRestClient()
1240
- response = client.get("/v1.0/myorg/dataflowStorageAccounts")
1241
- if response.status_code != 200:
1242
- raise FabricHTTPException(response)
1243
-
1244
- for v in response.json().get("value", []):
1245
- new_data = {
1246
- "Dataflow Storage Account ID": v.get("id"),
1247
- "Dataflow Storage Account Name": v.get("name"),
1248
- "Enabled": v.get("isEnabled"),
1249
- }
1250
- df = pd.concat([df, pd.DataFrame(new_data, index=[0])], ignore_index=True)
1251
-
1252
- df["Enabled"] = df["Enabled"].astype(bool)
1253
-
1254
- return df
1255
-
1256
-
1257
1332
  def list_kpis(dataset: str, workspace: Optional[str] = None) -> pd.DataFrame:
1258
1333
  """
1259
1334
  Shows a semantic model's KPIs and their properties.
@@ -1749,9 +1824,6 @@ def create_custom_pool(
1749
1824
  The name of the Fabric workspace.
1750
1825
  Defaults to None which resolves to the workspace of the attached lakehouse
1751
1826
  or if no lakehouse attached, resolves to the workspace of the notebook.
1752
-
1753
- Returns
1754
- -------
1755
1827
  """
1756
1828
 
1757
1829
  # https://learn.microsoft.com/en-us/rest/api/fabric/spark/custom-pools/create-workspace-custom-pool
@@ -1775,10 +1847,10 @@ def create_custom_pool(
1775
1847
 
1776
1848
  client = fabric.FabricRestClient()
1777
1849
  response = client.post(
1778
- f"/v1/workspaces/{workspace_id}/spark/pools", json=request_body, lro_wait=True
1850
+ f"/v1/workspaces/{workspace_id}/spark/pools", json=request_body
1779
1851
  )
1780
1852
 
1781
- if response.status_code != 200:
1853
+ if response.status_code != 201:
1782
1854
  raise FabricHTTPException(response)
1783
1855
  print(
1784
1856
  f"{icons.green_dot} The '{pool_name}' spark pool has been created within the '{workspace}' workspace."
@@ -1832,9 +1904,6 @@ def update_custom_pool(
1832
1904
  The name of the Fabric workspace.
1833
1905
  Defaults to None which resolves to the workspace of the attached lakehouse
1834
1906
  or if no lakehouse attached, resolves to the workspace of the notebook.
1835
-
1836
- Returns
1837
- -------
1838
1907
  """
1839
1908
 
1840
1909
  # https://learn.microsoft.com/en-us/rest/api/fabric/spark/custom-pools/update-workspace-custom-pool?tabs=HTTP
@@ -1907,9 +1976,6 @@ def delete_custom_pool(pool_name: str, workspace: Optional[str] = None):
1907
1976
  The name of the Fabric workspace.
1908
1977
  Defaults to None which resolves to the workspace of the attached lakehouse
1909
1978
  or if no lakehouse attached, resolves to the workspace of the notebook.
1910
-
1911
- Returns
1912
- -------
1913
1979
  """
1914
1980
 
1915
1981
  (workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
@@ -1945,15 +2011,16 @@ def assign_workspace_to_capacity(capacity_name: str, workspace: Optional[str] =
1945
2011
  The name of the Fabric workspace.
1946
2012
  Defaults to None which resolves to the workspace of the attached lakehouse
1947
2013
  or if no lakehouse attached, resolves to the workspace of the notebook.
1948
-
1949
- Returns
1950
- -------
1951
2014
  """
1952
2015
 
1953
2016
  (workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
1954
2017
 
1955
2018
  dfC = fabric.list_capacities()
1956
2019
  dfC_filt = dfC[dfC["Display Name"] == capacity_name]
2020
+
2021
+ if len(dfC_filt) == 0:
2022
+ raise ValueError(f"{icons.red_dot} The '{capacity_name}' capacity does not exist.")
2023
+
1957
2024
  capacity_id = dfC_filt["Id"].iloc[0]
1958
2025
 
1959
2026
  request_body = {"capacityId": capacity_id}
@@ -1962,7 +2029,6 @@ def assign_workspace_to_capacity(capacity_name: str, workspace: Optional[str] =
1962
2029
  response = client.post(
1963
2030
  f"/v1/workspaces/{workspace_id}/assignToCapacity",
1964
2031
  json=request_body,
1965
- lro_wait=True,
1966
2032
  )
1967
2033
 
1968
2034
  if response.status_code not in [200, 202]:
@@ -1982,9 +2048,6 @@ def unassign_workspace_from_capacity(workspace: Optional[str] = None):
1982
2048
  The name of the Fabric workspace.
1983
2049
  Defaults to None which resolves to the workspace of the attached lakehouse
1984
2050
  or if no lakehouse attached, resolves to the workspace of the notebook.
1985
-
1986
- Returns
1987
- -------
1988
2051
  """
1989
2052
 
1990
2053
  # https://learn.microsoft.com/en-us/rest/api/fabric/core/workspaces/unassign-from-capacity?tabs=HTTP
@@ -1992,7 +2055,7 @@ def unassign_workspace_from_capacity(workspace: Optional[str] = None):
1992
2055
 
1993
2056
  client = fabric.FabricRestClient()
1994
2057
  response = client.post(
1995
- f"/v1/workspaces/{workspace_id}/unassignFromCapacity", lro_wait=True
2058
+ f"/v1/workspaces/{workspace_id}/unassignFromCapacity"
1996
2059
  )
1997
2060
 
1998
2061
  if response.status_code not in [200, 202]:
@@ -2357,46 +2420,6 @@ def list_workspace_users(workspace: Optional[str] = None) -> pd.DataFrame:
2357
2420
  return df
2358
2421
 
2359
2422
 
2360
- def assign_workspace_to_dataflow_storage(
2361
- dataflow_storage_account: str, workspace: Optional[str] = None
2362
- ):
2363
- """
2364
- Assigns a dataflow storage account to a workspace.
2365
-
2366
- Parameters
2367
- ----------
2368
- dataflow_storage_account : str
2369
- The name of the dataflow storage account.
2370
- workspace : str, default=None
2371
- The name of the workspace.
2372
- Defaults to None which resolves to the workspace of the attached lakehouse
2373
- or if no lakehouse attached, resolves to the workspace of the notebook.
2374
-
2375
- Returns
2376
- -------
2377
- """
2378
-
2379
- (workspace, workspace_id) = resolve_workspace_name_and_id(workspace)
2380
-
2381
- df = list_dataflow_storage_accounts()
2382
- df_filt = df[df["Dataflow Storage Account Name"] == dataflow_storage_account]
2383
- dataflow_storage_id = df_filt["Dataflow Storage Account ID"].iloc[0]
2384
-
2385
- client = fabric.PowerBIRestClient()
2386
-
2387
- request_body = {"dataflowStorageId": dataflow_storage_id}
2388
-
2389
- response = client.post(
2390
- f"/v1.0/myorg/groups/{workspace_id}/AssignToDataflowStorage", json=request_body
2391
- )
2392
-
2393
- if response.status_code != 200:
2394
- raise FabricHTTPException(response)
2395
- print(
2396
- f"{icons.green_dot} The '{dataflow_storage_account}' dataflow storage account has been assigned to the '{workspace}' workspacce."
2397
- )
2398
-
2399
-
2400
2423
  def list_capacities() -> pd.DataFrame:
2401
2424
  """
2402
2425
  Shows the capacities and their properties.
sempy_labs/_model_bpa.py CHANGED
@@ -21,7 +21,6 @@ from sempy._utils._log import log
21
21
  import sempy_labs._icons as icons
22
22
  from pyspark.sql.functions import col, flatten
23
23
  from pyspark.sql.types import StructType, StructField, StringType
24
- import polib
25
24
  import os
26
25
 
27
26
 
@@ -64,8 +63,8 @@ def run_model_bpa(
64
63
  pandas.DataFrame
65
64
  A pandas dataframe in HTML format showing semantic model objects which violated the best practice analyzer rules.
66
65
  """
67
-
68
- from synapse.ml.services import Translate
66
+
67
+ import polib
69
68
 
70
69
  if "extend" in kwargs:
71
70
  print(
@@ -108,6 +107,7 @@ def run_model_bpa(
108
107
  "zu-ZA",
109
108
  "am-ET",
110
109
  "ar-AE",
110
+ "sv-SE",
111
111
  ]
112
112
 
113
113
  # Map languages to the closest language (first 2 letters matching)
@@ -162,86 +162,86 @@ def run_model_bpa(
162
162
  entry.msgstr
163
163
  )
164
164
 
165
- def translate_using_spark(rule_file):
166
- rules_temp = rule_file.copy()
167
- rules_temp = rules_temp.drop(["Expression", "URL", "Severity"], axis=1)
168
-
169
- schema = StructType(
170
- [
171
- StructField("Category", StringType(), True),
172
- StructField("Scope", StringType(), True),
173
- StructField("Rule Name", StringType(), True),
174
- StructField("Description", StringType(), True),
175
- ]
176
- )
165
+ translated = False
177
166
 
178
- spark = SparkSession.builder.getOrCreate()
179
- dfRules = spark.createDataFrame(rules_temp, schema)
180
-
181
- columns = ["Category", "Rule Name", "Description"]
182
- for clm in columns:
183
- translate = (
184
- Translate()
185
- .setTextCol(clm)
186
- .setToLanguage(language)
187
- .setOutputCol("translation")
188
- .setConcurrency(5)
167
+ # Translations
168
+ if language is not None and rules is None and language in language_list:
169
+ rules = model_bpa_rules(dependencies=dep)
170
+ translate_using_po(rules)
171
+ translated = True
172
+ if rules is None:
173
+ rules = model_bpa_rules(dependencies=dep)
174
+ if language is not None and not translated:
175
+
176
+ def translate_using_spark(rule_file):
177
+
178
+ from synapse.ml.services import Translate
179
+
180
+ rules_temp = rule_file.copy()
181
+ rules_temp = rules_temp.drop(["Expression", "URL", "Severity"], axis=1)
182
+
183
+ schema = StructType(
184
+ [
185
+ StructField("Category", StringType(), True),
186
+ StructField("Scope", StringType(), True),
187
+ StructField("Rule Name", StringType(), True),
188
+ StructField("Description", StringType(), True),
189
+ ]
189
190
  )
190
191
 
191
- if clm == "Rule Name":
192
- transDF = (
193
- translate.transform(dfRules)
194
- .withColumn(
195
- "translation", flatten(col("translation.translations"))
196
- )
197
- .withColumn("translation", col("translation.text"))
198
- .select(clm, "translation")
199
- )
200
- else:
201
- transDF = (
202
- translate.transform(dfRules)
203
- .withColumn(
204
- "translation", flatten(col("translation.translations"))
205
- )
206
- .withColumn("translation", col("translation.text"))
207
- .select("Rule Name", clm, "translation")
192
+ spark = SparkSession.builder.getOrCreate()
193
+ dfRules = spark.createDataFrame(rules_temp, schema)
194
+
195
+ columns = ["Category", "Rule Name", "Description"]
196
+ for clm in columns:
197
+ translate = (
198
+ Translate()
199
+ .setTextCol(clm)
200
+ .setToLanguage(language)
201
+ .setOutputCol("translation")
202
+ .setConcurrency(5)
208
203
  )
209
204
 
210
- df_panda = transDF.toPandas()
211
- rule_file = pd.merge(
212
- rule_file,
213
- df_panda[["Rule Name", "translation"]],
214
- on="Rule Name",
215
- how="left",
216
- )
205
+ if clm == "Rule Name":
206
+ transDF = (
207
+ translate.transform(dfRules)
208
+ .withColumn(
209
+ "translation", flatten(col("translation.translations"))
210
+ )
211
+ .withColumn("translation", col("translation.text"))
212
+ .select(clm, "translation")
213
+ )
214
+ else:
215
+ transDF = (
216
+ translate.transform(dfRules)
217
+ .withColumn(
218
+ "translation", flatten(col("translation.translations"))
219
+ )
220
+ .withColumn("translation", col("translation.text"))
221
+ .select("Rule Name", clm, "translation")
222
+ )
217
223
 
218
- rule_file = rule_file.rename(
219
- columns={"translation": f"{clm}Translated"}
220
- )
221
- rule_file[f"{clm}Translated"] = rule_file[f"{clm}Translated"].apply(
222
- lambda x: x[0] if x is not None else None
223
- )
224
+ df_panda = transDF.toPandas()
225
+ rule_file = pd.merge(
226
+ rule_file,
227
+ df_panda[["Rule Name", "translation"]],
228
+ on="Rule Name",
229
+ how="left",
230
+ )
224
231
 
225
- for clm in columns:
226
- rule_file = rule_file.drop([clm], axis=1)
227
- rule_file = rule_file.rename(columns={f"{clm}Translated": clm})
232
+ rule_file = rule_file.rename(
233
+ columns={"translation": f"{clm}Translated"}
234
+ )
235
+ rule_file[f"{clm}Translated"] = rule_file[f"{clm}Translated"].apply(
236
+ lambda x: x[0] if x is not None else None
237
+ )
228
238
 
229
- return rule_file
239
+ for clm in columns:
240
+ rule_file = rule_file.drop([clm], axis=1)
241
+ rule_file = rule_file.rename(columns={f"{clm}Translated": clm})
230
242
 
231
- translated = False
243
+ return rule_file
232
244
 
233
- # Translations
234
- if language is not None and rules is None and language in language_list:
235
- rules = model_bpa_rules(
236
- dataset=dataset, workspace=workspace, dependencies=dep
237
- )
238
- translate_using_po(rules)
239
- translated = True
240
- if rules is None:
241
- rules = model_bpa_rules(
242
- dataset=dataset, workspace=workspace, dependencies=dep
243
- )
244
- if language is not None and not translated:
245
245
  rules = translate_using_spark(rules)
246
246
 
247
247
  rules["Severity"].replace("Warning", icons.warning, inplace=True)
@@ -302,26 +302,28 @@ def run_model_bpa(
302
302
 
303
303
  if scope == "Model":
304
304
  x = []
305
- if expr(func):
305
+ if expr(func, tom):
306
306
  x = ["Model"]
307
307
  elif scope == "Measure":
308
- x = [nm(obj) for obj in tom.all_measures() if expr(obj)]
308
+ x = [nm(obj) for obj in tom.all_measures() if expr(obj, tom)]
309
309
  elif scope == "Column":
310
- x = [nm(obj) for obj in tom.all_columns() if expr(obj)]
310
+ x = [nm(obj) for obj in tom.all_columns() if expr(obj, tom)]
311
311
  elif scope == "Partition":
312
- x = [nm(obj) for obj in tom.all_partitions() if expr(obj)]
312
+ x = [nm(obj) for obj in tom.all_partitions() if expr(obj, tom)]
313
313
  elif scope == "Hierarchy":
314
- x = [nm(obj) for obj in tom.all_hierarchies() if expr(obj)]
314
+ x = [nm(obj) for obj in tom.all_hierarchies() if expr(obj, tom)]
315
315
  elif scope == "Table":
316
- x = [nm(obj) for obj in tom.model.Tables if expr(obj)]
316
+ x = [nm(obj) for obj in tom.model.Tables if expr(obj, tom)]
317
317
  elif scope == "Relationship":
318
- x = [nm(obj) for obj in tom.model.Relationships if expr(obj)]
318
+ x = [nm(obj) for obj in tom.model.Relationships if expr(obj, tom)]
319
319
  elif scope == "Role":
320
- x = [nm(obj) for obj in tom.model.Roles if expr(obj)]
320
+ x = [nm(obj) for obj in tom.model.Roles if expr(obj, tom)]
321
321
  elif scope == "Row Level Security":
322
- x = [nm(obj) for obj in tom.all_rls() if expr(obj)]
322
+ x = [nm(obj) for obj in tom.all_rls() if expr(obj, tom)]
323
323
  elif scope == "Calculation Item":
324
- x = [nm(obj) for obj in tom.all_calculation_items() if expr(obj)]
324
+ x = [
325
+ nm(obj) for obj in tom.all_calculation_items() if expr(obj, tom)
326
+ ]
325
327
 
326
328
  if len(x) > 0:
327
329
  new_data = {"Object Name": x, "Scope": scope, "Rule Name": ruleName}
@@ -229,7 +229,9 @@ def create_model_bpa_semantic_model(
229
229
  expr = get_shared_expression(lakehouse=lakehouse, workspace=lakehouse_workspace)
230
230
 
231
231
  # Create blank model
232
- create_blank_semantic_model(dataset=dataset, workspace=lakehouse_workspace)
232
+ create_blank_semantic_model(
233
+ dataset=dataset, workspace=lakehouse_workspace, overwrite=True
234
+ )
233
235
 
234
236
  @retry(
235
237
  sleep_time=1,