semantic-link-labs 0.5.0__py3-none-any.whl → 0.7.0__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 (113) hide show
  1. semantic_link_labs-0.7.0.dist-info/METADATA +148 -0
  2. semantic_link_labs-0.7.0.dist-info/RECORD +111 -0
  3. {semantic_link_labs-0.5.0.dist-info → semantic_link_labs-0.7.0.dist-info}/WHEEL +1 -1
  4. sempy_labs/__init__.py +45 -15
  5. sempy_labs/_ai.py +42 -85
  6. sempy_labs/_bpa_translation/_translations_am-ET.po +828 -0
  7. sempy_labs/_bpa_translation/_translations_ar-AE.po +860 -0
  8. sempy_labs/_bpa_translation/_translations_cs-CZ.po +894 -0
  9. sempy_labs/_bpa_translation/_translations_da-DK.po +894 -0
  10. sempy_labs/_bpa_translation/_translations_de-DE.po +933 -0
  11. sempy_labs/_bpa_translation/_translations_el-GR.po +936 -0
  12. sempy_labs/_bpa_translation/_translations_es-ES.po +915 -0
  13. sempy_labs/_bpa_translation/_translations_fa-IR.po +883 -0
  14. sempy_labs/_bpa_translation/_translations_fr-FR.po +938 -0
  15. sempy_labs/_bpa_translation/_translations_ga-IE.po +912 -0
  16. sempy_labs/_bpa_translation/_translations_he-IL.po +855 -0
  17. sempy_labs/_bpa_translation/_translations_hi-IN.po +892 -0
  18. sempy_labs/_bpa_translation/_translations_hu-HU.po +910 -0
  19. sempy_labs/_bpa_translation/_translations_is-IS.po +887 -0
  20. sempy_labs/_bpa_translation/_translations_it-IT.po +931 -0
  21. sempy_labs/_bpa_translation/_translations_ja-JP.po +805 -0
  22. sempy_labs/_bpa_translation/_translations_nl-NL.po +924 -0
  23. sempy_labs/_bpa_translation/_translations_pl-PL.po +913 -0
  24. sempy_labs/_bpa_translation/_translations_pt-BR.po +909 -0
  25. sempy_labs/_bpa_translation/_translations_pt-PT.po +904 -0
  26. sempy_labs/_bpa_translation/_translations_ru-RU.po +909 -0
  27. sempy_labs/_bpa_translation/_translations_ta-IN.po +922 -0
  28. sempy_labs/_bpa_translation/_translations_te-IN.po +896 -0
  29. sempy_labs/_bpa_translation/_translations_th-TH.po +873 -0
  30. sempy_labs/_bpa_translation/_translations_zh-CN.po +767 -0
  31. sempy_labs/_bpa_translation/_translations_zu-ZA.po +916 -0
  32. sempy_labs/_clear_cache.py +12 -8
  33. sempy_labs/_connections.py +77 -70
  34. sempy_labs/_dax.py +7 -9
  35. sempy_labs/_generate_semantic_model.py +75 -90
  36. sempy_labs/_helper_functions.py +371 -20
  37. sempy_labs/_icons.py +23 -0
  38. sempy_labs/_list_functions.py +855 -427
  39. sempy_labs/_model_auto_build.py +4 -3
  40. sempy_labs/_model_bpa.py +307 -1118
  41. sempy_labs/_model_bpa_bulk.py +363 -0
  42. sempy_labs/_model_bpa_rules.py +831 -0
  43. sempy_labs/_model_dependencies.py +20 -16
  44. sempy_labs/_one_lake_integration.py +18 -12
  45. sempy_labs/_query_scale_out.py +116 -129
  46. sempy_labs/_refresh_semantic_model.py +23 -10
  47. sempy_labs/_translations.py +367 -288
  48. sempy_labs/_vertipaq.py +152 -123
  49. sempy_labs/directlake/__init__.py +7 -1
  50. sempy_labs/directlake/_directlake_schema_compare.py +33 -30
  51. sempy_labs/directlake/_directlake_schema_sync.py +60 -77
  52. sempy_labs/directlake/_dl_helper.py +233 -0
  53. sempy_labs/directlake/_get_directlake_lakehouse.py +7 -8
  54. sempy_labs/directlake/_get_shared_expression.py +5 -3
  55. sempy_labs/directlake/_guardrails.py +20 -16
  56. sempy_labs/directlake/_list_directlake_model_calc_tables.py +17 -10
  57. sempy_labs/directlake/_show_unsupported_directlake_objects.py +3 -2
  58. sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +10 -5
  59. sempy_labs/directlake/_update_directlake_partition_entity.py +169 -22
  60. sempy_labs/directlake/_warm_cache.py +7 -4
  61. sempy_labs/lakehouse/_get_lakehouse_columns.py +1 -1
  62. sempy_labs/lakehouse/_get_lakehouse_tables.py +65 -71
  63. sempy_labs/lakehouse/_lakehouse.py +5 -3
  64. sempy_labs/lakehouse/_shortcuts.py +20 -13
  65. sempy_labs/migration/__init__.py +1 -1
  66. sempy_labs/migration/_create_pqt_file.py +184 -186
  67. sempy_labs/migration/_migrate_calctables_to_lakehouse.py +240 -269
  68. sempy_labs/migration/_migrate_calctables_to_semantic_model.py +78 -77
  69. sempy_labs/migration/_migrate_model_objects_to_semantic_model.py +444 -425
  70. sempy_labs/migration/_migrate_tables_columns_to_semantic_model.py +96 -102
  71. sempy_labs/migration/_migration_validation.py +2 -2
  72. sempy_labs/migration/_refresh_calc_tables.py +94 -100
  73. sempy_labs/report/_BPAReportTemplate.json +232 -0
  74. sempy_labs/report/__init__.py +6 -2
  75. sempy_labs/report/_bpareporttemplate/.pbi/localSettings.json +9 -0
  76. sempy_labs/report/_bpareporttemplate/.platform +11 -0
  77. sempy_labs/report/_bpareporttemplate/StaticResources/SharedResources/BaseThemes/CY24SU06.json +710 -0
  78. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/page.json +11 -0
  79. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/1b08bce3bebabb0a27a8/visual.json +191 -0
  80. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/2f22ddb70c301693c165/visual.json +438 -0
  81. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/3b1182230aa6c600b43a/visual.json +127 -0
  82. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/58577ba6380c69891500/visual.json +576 -0
  83. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/a2a8fa5028b3b776c96c/visual.json +207 -0
  84. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/adfd47ef30652707b987/visual.json +506 -0
  85. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/b6a80ee459e716e170b1/visual.json +127 -0
  86. sempy_labs/report/_bpareporttemplate/definition/pages/01d72098bda5055bd500/visuals/ce3130a721c020cc3d81/visual.json +513 -0
  87. sempy_labs/report/_bpareporttemplate/definition/pages/92735ae19b31712208ad/page.json +8 -0
  88. sempy_labs/report/_bpareporttemplate/definition/pages/92735ae19b31712208ad/visuals/66e60dfb526437cd78d1/visual.json +112 -0
  89. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/page.json +11 -0
  90. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/07deb8bce824e1be37d7/visual.json +513 -0
  91. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/0b1c68838818b32ad03b/visual.json +352 -0
  92. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/0c171de9d2683d10b930/visual.json +37 -0
  93. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/0efa01be0510e40a645e/visual.json +542 -0
  94. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/6bf2f0eb830ab53cc668/visual.json +221 -0
  95. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/88d8141cb8500b60030c/visual.json +127 -0
  96. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/a753273590beed656a03/visual.json +576 -0
  97. sempy_labs/report/_bpareporttemplate/definition/pages/c597da16dc7e63222a82/visuals/b8fdc82cddd61ac447bc/visual.json +127 -0
  98. sempy_labs/report/_bpareporttemplate/definition/pages/d37dce724a0ccc30044b/page.json +9 -0
  99. sempy_labs/report/_bpareporttemplate/definition/pages/d37dce724a0ccc30044b/visuals/ce8532a7e25020271077/visual.json +38 -0
  100. sempy_labs/report/_bpareporttemplate/definition/pages/pages.json +10 -0
  101. sempy_labs/report/_bpareporttemplate/definition/report.json +176 -0
  102. sempy_labs/report/_bpareporttemplate/definition/version.json +4 -0
  103. sempy_labs/report/_bpareporttemplate/definition.pbir +14 -0
  104. sempy_labs/report/_generate_report.py +260 -139
  105. sempy_labs/report/_report_functions.py +90 -59
  106. sempy_labs/report/_report_rebind.py +40 -34
  107. sempy_labs/tom/__init__.py +1 -4
  108. sempy_labs/tom/_model.py +601 -181
  109. semantic_link_labs-0.5.0.dist-info/METADATA +0 -22
  110. semantic_link_labs-0.5.0.dist-info/RECORD +0 -53
  111. sempy_labs/directlake/_fallback.py +0 -58
  112. {semantic_link_labs-0.5.0.dist-info → semantic_link_labs-0.7.0.dist-info}/LICENSE +0 -0
  113. {semantic_link_labs-0.5.0.dist-info → semantic_link_labs-0.7.0.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,4 @@
1
+ import sempy
1
2
  import pandas as pd
2
3
  from typing import List, Optional, Union
3
4
  from sempy._utils._log import log
@@ -10,7 +11,7 @@ def translate_semantic_model(
10
11
  languages: Union[str, List[str]],
11
12
  exclude_characters: Optional[str] = None,
12
13
  workspace: Optional[str] = None,
13
- ):
14
+ ) -> pd.DataFrame:
14
15
  """
15
16
  Translates names, descriptions, display folders for all objects in a semantic model.
16
17
 
@@ -29,6 +30,8 @@ def translate_semantic_model(
29
30
 
30
31
  Returns
31
32
  -------
33
+ pandas.DataFrame
34
+ Shows a pandas dataframe which displays all of the translations in the semantic model.
32
35
 
33
36
  """
34
37
 
@@ -37,10 +40,16 @@ def translate_semantic_model(
37
40
  from pyspark.sql import SparkSession
38
41
  from sempy_labs.tom import connect_semantic_model
39
42
 
43
+ def clean_text(text, exclude_chars):
44
+ if exclude_chars:
45
+ for char in exclude_chars:
46
+ text = text.replace(char, " ")
47
+ return text
48
+
40
49
  if isinstance(languages, str):
41
50
  languages = [languages]
42
51
 
43
- dfPrep = pd.DataFrame(
52
+ df_prep = pd.DataFrame(
44
53
  columns=["Object Type", "Name", "Description", "Display Folder"]
45
54
  )
46
55
 
@@ -48,141 +57,87 @@ def translate_semantic_model(
48
57
  dataset=dataset, readonly=False, workspace=workspace
49
58
  ) as tom:
50
59
 
51
- if exclude_characters is None:
52
- for o in tom.model.Tables:
53
- new_data = {
54
- "Object Type": "Table",
55
- "Name": o.Name,
56
- "TName": o.Name,
57
- "Description": o.Description,
58
- "TDescription": o.Description,
59
- "Display Folder": None,
60
- "TDisplay Folder": None,
61
- }
62
- dfPrep = pd.concat(
63
- [dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
64
- )
65
- for o in tom.all_columns():
66
- new_data = {
67
- "Object Type": "Column",
68
- "Name": o.Name,
69
- "TName": o.Name,
70
- "Description": o.Description,
71
- "TDescription": o.Description,
72
- "Display Folder": o.DisplayFolder,
73
- "TDisplay Folder": o.DisplayFolder,
74
- }
75
- dfPrep = pd.concat(
76
- [dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
77
- )
78
- for o in tom.all_measures():
79
- new_data = {
80
- "Object Type": "Measure",
81
- "Name": o.Name,
82
- "TName": o.Name,
83
- "Description": o.Description,
84
- "TDescription": o.Description,
85
- "Display Folder": o.DisplayFolder,
86
- "TDisplay Folder": o.DisplayFolder,
87
- }
88
- dfPrep = pd.concat(
89
- [dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
90
- )
91
- for o in tom.all_hierarchies():
92
- new_data = {
93
- "Object Type": "Hierarchy",
94
- "Name": o.Name,
95
- "TName": o.Name,
96
- "Description": o.Description,
97
- "TDescription": o.Description,
98
- "Display Folder": o.DisplayFolder,
99
- "TDisplay Folder": o.DisplayFolder,
100
- }
101
- dfPrep = pd.concat(
102
- [dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
103
- )
104
- else:
105
- for o in tom.model.Tables:
106
- oName = o.Name
107
- oDescription = o.Description
108
- for s in exclude_characters:
109
- oName = oName.replace(s, " ")
110
- oDescription = oDescription.replace(s, " ")
111
- new_data = {
112
- "Object Type": "Table",
113
- "Name": o.Name,
114
- "TName": oName,
115
- "Description": o.Description,
116
- "TDescription": oDescription,
117
- "Display Folder": None,
118
- "TDisplay Folder": None,
119
- }
120
- dfPrep = pd.concat(
121
- [dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
122
- )
123
- for o in tom.all_columns():
124
- oName = o.Name
125
- oDescription = o.Description
126
- oDisplayFolder = o.DisplayFolder
127
- for s in exclude_characters:
128
- oName = oName.replace(s, " ")
129
- oDescription = oDescription.replace(s, " ")
130
- oDisplayFolder = oDisplayFolder.replace(s, " ")
131
- new_data = {
132
- "Object Type": "Column",
133
- "Name": o.Name,
134
- "TName": oName,
135
- "Description": o.Description,
136
- "TDescription": oDescription,
137
- "Display Folder": o.DisplayFolder,
138
- "TDisplay Folder": oDisplayFolder,
139
- }
140
- dfPrep = pd.concat(
141
- [dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
142
- )
143
- for o in tom.all_measures():
144
- oName = o.Name
145
- oDescription = o.Description
146
- oDisplayFolder = o.DisplayFolder
147
- for s in exclude_characters:
148
- oName = oName.replace(s, " ")
149
- oDescription = oDescription.replace(s, " ")
150
- oDisplayFolder = oDisplayFolder.replace(s, " ")
151
- new_data = {
152
- "Object Type": "Measure",
153
- "Name": o.Name,
154
- "TName": oName,
155
- "Description": o.Description,
156
- "TDescription": oDescription,
157
- "Display Folder": o.DisplayFolder,
158
- "TDisplay Folder": oDisplayFolder,
159
- }
160
- dfPrep = pd.concat(
161
- [dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
162
- )
163
- for o in tom.all_hierarchies():
164
- oName = o.Name
165
- oDescription = o.Description
166
- oDisplayFolder = o.DisplayFolder
167
- for s in exclude_characters:
168
- oName = oName.replace(s, " ")
169
- oDescription = oDescription.replace(s, " ")
170
- oDisplayFolder = oDisplayFolder.replace(s, " ")
171
- new_data = {
172
- "Object Type": "Hierarchy",
173
- "Name": o.Name,
174
- "TName": oName,
175
- "Description": o.Description,
176
- "TDescription": oDescription,
177
- "Display Folder": o.DisplayFolder,
178
- "TDisplay Folder": oDisplayFolder,
179
- }
180
- dfPrep = pd.concat(
181
- [dfPrep, pd.DataFrame(new_data, index=[0])], ignore_index=True
182
- )
60
+ for o in tom.model.Tables:
61
+ oName = clean_text(o.Name, exclude_characters)
62
+ oDescription = clean_text(o.Description, exclude_characters)
63
+ new_data = {
64
+ "Object Type": "Table",
65
+ "Name": o.Name,
66
+ "TName": oName,
67
+ "Description": o.Description,
68
+ "TDescription": oDescription,
69
+ "Display Folder": None,
70
+ "TDisplay Folder": None,
71
+ }
72
+ df_prep = pd.concat(
73
+ [df_prep, pd.DataFrame(new_data, index=[0])], ignore_index=True
74
+ )
75
+ for o in tom.all_columns():
76
+ oName = clean_text(o.Name, exclude_characters)
77
+ oDescription = clean_text(o.Description, exclude_characters)
78
+ oDisplayFolder = clean_text(o.DisplayFolder, exclude_characters)
79
+ new_data = {
80
+ "Object Type": "Column",
81
+ "Name": o.Name,
82
+ "TName": oName,
83
+ "Description": o.Description,
84
+ "TDescription": oDescription,
85
+ "Display Folder": o.DisplayFolder,
86
+ "TDisplay Folder": oDisplayFolder,
87
+ }
88
+ df_prep = pd.concat(
89
+ [df_prep, pd.DataFrame(new_data, index=[0])], ignore_index=True
90
+ )
91
+ for o in tom.all_measures():
92
+ oName = clean_text(o.Name, exclude_characters)
93
+ oDescription = clean_text(o.Description, exclude_characters)
94
+ oDisplayFolder = clean_text(o.DisplayFolder, exclude_characters)
95
+ new_data = {
96
+ "Object Type": "Measure",
97
+ "Name": o.Name,
98
+ "TName": oName,
99
+ "Description": o.Description,
100
+ "TDescription": oDescription,
101
+ "Display Folder": o.DisplayFolder,
102
+ "TDisplay Folder": oDisplayFolder,
103
+ }
104
+ df_prep = pd.concat(
105
+ [df_prep, pd.DataFrame(new_data, index=[0])], ignore_index=True
106
+ )
107
+ for o in tom.all_hierarchies():
108
+ oName = clean_text(o.Name, exclude_characters)
109
+ oDescription = clean_text(o.Description, exclude_characters)
110
+ oDisplayFolder = clean_text(o.DisplayFolder, exclude_characters)
111
+ new_data = {
112
+ "Object Type": "Hierarchy",
113
+ "Name": o.Name,
114
+ "TName": oName,
115
+ "Description": o.Description,
116
+ "TDescription": oDescription,
117
+ "Display Folder": o.DisplayFolder,
118
+ "TDisplay Folder": oDisplayFolder,
119
+ }
120
+ df_prep = pd.concat(
121
+ [df_prep, pd.DataFrame(new_data, index=[0])], ignore_index=True
122
+ )
123
+ for o in tom.all_levels():
124
+ oName = clean_text(o.Name, exclude_characters)
125
+ oDescription = clean_text(o.Description, exclude_characters)
126
+ new_data = {
127
+ "Object Type": "Level",
128
+ "Name": o.Name,
129
+ "TName": oName,
130
+ "Description": o.Description,
131
+ "TDescription": oDescription,
132
+ "Display Folder": None,
133
+ "TDisplay Folder": None,
134
+ }
135
+ df_prep = pd.concat(
136
+ [df_prep, pd.DataFrame(new_data, index=[0])], ignore_index=True
137
+ )
183
138
 
184
139
  spark = SparkSession.builder.getOrCreate()
185
- df = spark.createDataFrame(dfPrep)
140
+ df = spark.createDataFrame(df_prep)
186
141
 
187
142
  columns = ["Name", "Description", "Display Folder"]
188
143
 
@@ -204,175 +159,299 @@ def translate_semantic_model(
204
159
  )
205
160
 
206
161
  df_panda = transDF.toPandas()
207
- print(f"{icons.in_progress} Translating {clm}s...")
162
+
163
+ def set_translation_if_exists(
164
+ obj, obj_type, property_name, property_value, df, lang, index
165
+ ):
166
+ if property_name in df.columns and len(property_value) > 0:
167
+ df_filt = df[
168
+ (df["Object Type"] == obj_type)
169
+ & (df[property_name] == property_value)
170
+ ]
171
+ if len(df_filt) == 1:
172
+ translation = df_filt["translation"].str[index].iloc[0]
173
+ tom.set_translation(
174
+ object=obj,
175
+ language=lang,
176
+ property=property_name,
177
+ value=translation,
178
+ )
208
179
 
209
180
  for lang in languages:
210
181
  i = languages.index(lang)
211
182
  tom.add_translation(language=lang)
212
- print(f"{icons.in_progress} Translating into the '{lang}' language...")
183
+ print(
184
+ f"{icons.in_progress} Translating {clm.lower()}s into the '{lang}' language..."
185
+ )
213
186
 
214
187
  for t in tom.model.Tables:
215
188
  if t.IsHidden is False:
216
189
  if clm == "Name":
217
- df_filt = df_panda[
218
- (df_panda["Object Type"] == "Table")
219
- & (df_panda["Name"] == t.Name)
220
- ]
221
- if len(df_filt) == 1:
222
- tr = df_filt["translation"].str[i].iloc[0]
223
- tom.set_translation(
224
- object=t, language=lang, property="Name", value=tr
225
- )
226
- print(
227
- f"{icons.green_dot} Translation '{tr}' set for the '{lang}' language on the '{t.Name}' table."
228
- )
229
- elif clm == "Description" and t.Description is not None:
230
- df_filt = df_panda[
231
- (df_panda["Object Type"] == "Table")
232
- & (df_panda["Description"] == t.Description)
233
- ]
234
- if len(df_filt) == 1:
235
- tr = df_filt["translation"].str[i].iloc[0]
236
- tom.set_translation(
237
- object=t,
238
- language=lang,
239
- property="Description",
240
- value=tr,
241
- )
190
+ set_translation_if_exists(
191
+ t, "Table", "Name", t.Name, df_panda, lang, i
192
+ )
193
+ elif clm == "Description":
194
+ set_translation_if_exists(
195
+ t,
196
+ "Table",
197
+ "Description",
198
+ t.Description,
199
+ df_panda,
200
+ lang,
201
+ i,
202
+ )
242
203
  for c in t.Columns:
243
204
  if c.IsHidden is False:
244
205
  if clm == "Name":
245
- df_filt = df_panda[
246
- (df_panda["Object Type"] == "Column")
247
- & (df_panda["Name"] == c.Name)
248
- ]
249
- if len(df_filt) == 1:
250
- tr = df_filt["translation"].str[i].iloc[0]
251
- tom.set_translation(
252
- object=c,
253
- language=lang,
254
- property="Name",
255
- value=tr,
256
- )
257
- print(
258
- f"{icons.green_dot} Translation '{tr}' set on the '{c.Name}' column within the {t.Name}' table."
259
- )
260
- elif clm == "Description" and c.Description is not None:
261
- df_filt = df_panda[
262
- (df_panda["Object Type"] == "Column")
263
- & (df_panda["Description"] == c.Description)
264
- ]
265
- if len(df_filt) == 1:
266
- tr = df_filt["translation"].str[i].iloc[0]
267
- tom.set_translation(
268
- object=c,
269
- language=lang,
270
- property="Description",
271
- value=tr,
272
- )
273
- elif (
274
- clm == "Display Folder"
275
- and c.DisplayFolder is not None
276
- ):
277
- df_filt = df_panda[
278
- (df_panda["Object Type"] == "Column")
279
- & (df_panda["Display Folder"] == c.Description)
280
- ]
281
- if len(df_filt) == 1:
282
- tr = df_filt["translation"].str[i].iloc[0]
283
- tom.set_translation(
284
- object=c,
285
- language=lang,
286
- property="Display Folder",
287
- value=tr,
288
- )
206
+ set_translation_if_exists(
207
+ c, "Column", "Name", c.Name, df_panda, lang, i
208
+ )
209
+ elif clm == "Description":
210
+ set_translation_if_exists(
211
+ c,
212
+ "Column",
213
+ "Description",
214
+ c.Description,
215
+ df_panda,
216
+ lang,
217
+ i,
218
+ )
219
+ elif clm == "Display Folder":
220
+ set_translation_if_exists(
221
+ c,
222
+ "Column",
223
+ "Display Folder",
224
+ c.DisplayFolder,
225
+ df_panda,
226
+ lang,
227
+ i,
228
+ )
289
229
  for h in t.Hierarchies:
290
230
  if h.IsHidden is False:
291
231
  if clm == "Name":
292
- df_filt = df_panda[
293
- (df_panda["Object Type"] == "Hierarchy")
294
- & (df_panda["Name"] == h.Name)
295
- ]
296
- if len(df_filt) == 1:
297
- tr = df_filt["translation"].str[i].iloc[0]
298
- tom.set_translation(
299
- object=h,
300
- language=lang,
301
- property="Name",
302
- value=tr,
303
- )
304
- elif clm == "Description" and h.Description is not None:
305
- df_filt = df_panda[
306
- (df_panda["Object Type"] == "Hierarchy")
307
- & (df_panda["Description"] == h.Description)
308
- ]
309
- if len(df_filt) == 1:
310
- tr = df_filt["translation"].str[i].iloc[0]
311
- tom.set_translation(
312
- object=h,
313
- language=lang,
314
- property="Description",
315
- value=tr,
232
+ set_translation_if_exists(
233
+ h,
234
+ "Hierarchy",
235
+ "Name",
236
+ h.Name,
237
+ df_panda,
238
+ lang,
239
+ i,
240
+ )
241
+ elif clm == "Description":
242
+ set_translation_if_exists(
243
+ h,
244
+ "Hierarchy",
245
+ "Description",
246
+ h.Description,
247
+ df_panda,
248
+ lang,
249
+ i,
250
+ )
251
+ elif clm == "Display Folder":
252
+ set_translation_if_exists(
253
+ h,
254
+ "Hierarchy",
255
+ "Display Folder",
256
+ h.DisplayFolder,
257
+ df_panda,
258
+ lang,
259
+ i,
260
+ )
261
+ for lev in h.Levels:
262
+ if clm == "Name":
263
+ set_translation_if_exists(
264
+ lev,
265
+ "Level",
266
+ "Name",
267
+ lev.Name,
268
+ df_panda,
269
+ lang,
270
+ i,
316
271
  )
317
- elif (
318
- clm == "Display Folder"
319
- and h.DisplayFolder is not None
320
- ):
321
- df_filt = df_panda[
322
- (df_panda["Object Type"] == "Hierarchy")
323
- & (df_panda["Display Folder"] == h.Description)
324
- ]
325
- if len(df_filt) == 1:
326
- tr = df_filt["translation"].str[i].iloc[0]
327
- tom.set_translation(
328
- object=h,
329
- language=lang,
330
- property="Display Folder",
331
- value=tr,
272
+ elif clm == "Description":
273
+ set_translation_if_exists(
274
+ lev,
275
+ "Level",
276
+ "Description",
277
+ lev.Description,
278
+ df_panda,
279
+ lang,
280
+ i,
332
281
  )
333
282
  for ms in t.Measures:
334
283
  if ms.IsHidden is False:
335
284
  if clm == "Name":
336
- df_filt = df_panda[
337
- (df_panda["Object Type"] == "Measure")
338
- & (df_panda["Name"] == ms.Name)
339
- ]
340
- if len(df_filt) == 1:
341
- tr = df_filt["translation"].str[i].iloc[0]
342
- tom.set_translation(
343
- object=ms,
344
- language=lang,
345
- property="Name",
346
- value=tr,
347
- )
348
- print(
349
- f"{icons.green_dot} Translation '{tr}' set on the '{ms.Name}' column within the {t.Name}' table."
350
- )
351
- elif clm == "Description" and ms.Description is not None:
352
- df_filt = df_panda[
353
- (df_panda["Object Type"] == "Measure")
354
- & (df_panda["Description"] == ms.Description)
355
- ]
356
- if len(df_filt) == 1:
357
- tr = df_filt["translation"].str[i].iloc[0]
358
- tom.set_translation(
359
- object=ms,
360
- language=lang,
361
- property="Description",
362
- value=tr,
363
- )
364
- elif (
365
- clm == "Display Folder" and ms.DisplayFolder is not None
366
- ):
367
- df_filt = df_panda[
368
- (df_panda["Object Type"] == "Measure")
369
- & (df_panda["Display Folder"] == ms.Description)
370
- ]
371
- if len(df_filt) == 1:
372
- tr = df_filt["translation"].str[i].iloc[0]
373
- tom.set_translation(
374
- object=ms,
375
- language=lang,
376
- property="Display Folder",
377
- value=tr,
378
- )
285
+ set_translation_if_exists(
286
+ ms, "Measure", "Name", ms.Name, df_panda, lang, i
287
+ )
288
+ elif clm == "Description":
289
+ set_translation_if_exists(
290
+ ms,
291
+ "Measure",
292
+ "Description",
293
+ ms.Description,
294
+ df_panda,
295
+ lang,
296
+ i,
297
+ )
298
+ elif clm == "Display Folder":
299
+ set_translation_if_exists(
300
+ ms,
301
+ "Measure",
302
+ "Display Folder",
303
+ ms.DisplayFolder,
304
+ df_panda,
305
+ lang,
306
+ i,
307
+ )
308
+ result = pd.DataFrame(
309
+ columns=[
310
+ "Language",
311
+ "Object Type",
312
+ "Table Name",
313
+ "Object Name",
314
+ "Translated Object Name",
315
+ "Description",
316
+ "Translated Description",
317
+ "Display Folder",
318
+ "Translated Display Folder",
319
+ ]
320
+ )
321
+ with connect_semantic_model(
322
+ dataset=dataset, readonly=True, workspace=workspace
323
+ ) as tom:
324
+
325
+ sempy.fabric._client._utils._init_analysis_services()
326
+ import Microsoft.AnalysisServices.Tabular as TOM
327
+
328
+ for c in tom.model.Cultures:
329
+ for tr in c.ObjectTranslations:
330
+ oType = str(tr.Object.ObjectType)
331
+ oName = tr.Object.Name
332
+ tValue = tr.Value
333
+ prop = str(tr.Property)
334
+
335
+ if tr.Object.ObjectType == TOM.ObjectType.Table:
336
+ desc = tom.model.Tables[oName].Description
337
+ new_data = {
338
+ "Language": c.Name,
339
+ "Table Name": oName,
340
+ "Object Name": oName,
341
+ "Object Type": oType,
342
+ "Description": desc,
343
+ }
344
+ result = pd.concat(
345
+ [result, pd.DataFrame(new_data, index=[0])], ignore_index=True
346
+ )
347
+ condition = (
348
+ (result["Language"] == c.Name)
349
+ & (result["Table Name"] == oName)
350
+ & (result["Object Name"] == oName)
351
+ & (result["Object Type"] == oType)
352
+ )
353
+ elif tr.Object.ObjectType == TOM.ObjectType.Level:
354
+ hierarchyName = tr.Object.Parent.Name
355
+ tName = tr.Object.Parent.Parent.Name
356
+ levelName = "'" + hierarchyName + "'[" + oName + "]"
357
+ desc = (
358
+ tom.model.Tables[tName]
359
+ .Hierarchies[hierarchyName]
360
+ .Levels[oName]
361
+ .Description
362
+ )
363
+ new_data = {
364
+ "Language": c.Name,
365
+ "Table Name": tName,
366
+ "Object Name": levelName,
367
+ "Object Type": oType,
368
+ "Description": desc,
369
+ }
370
+ result = pd.concat(
371
+ [result, pd.DataFrame(new_data, index=[0])], ignore_index=True
372
+ )
373
+ condition = (
374
+ (result["Language"] == c.Name)
375
+ & (result["Table Name"] == tName)
376
+ & (result["Object Name"] == levelName)
377
+ & (result["Object Type"] == oType)
378
+ )
379
+ elif tr.Object.ObjectType == TOM.ObjectType.Column:
380
+ tName = tr.Object.Table.Name
381
+ desc = tom.model.Tables[tName].Columns[oName].Description
382
+ display_folder = (
383
+ tom.model.Tables[tName].Columns[oName].DisplayFolder
384
+ )
385
+ new_data = {
386
+ "Language": c.Name,
387
+ "Table Name": tName,
388
+ "Object Name": oName,
389
+ "Object Type": oType,
390
+ "Description": desc,
391
+ "Display Folder": display_folder,
392
+ }
393
+ result = pd.concat(
394
+ [result, pd.DataFrame(new_data, index=[0])], ignore_index=True
395
+ )
396
+ condition = (
397
+ (result["Language"] == c.Name)
398
+ & (result["Table Name"] == tName)
399
+ & (result["Object Name"] == oName)
400
+ & (result["Object Type"] == oType)
401
+ )
402
+ elif tr.Object.ObjectType == TOM.ObjectType.Measure:
403
+ tName = tr.Object.Table.Name
404
+ desc = tom.model.Tables[tName].Measures[oName].Description
405
+ display_folder = (
406
+ tom.model.Tables[tName].Measures[oName].DisplayFolder
407
+ )
408
+ new_data = {
409
+ "Language": c.Name,
410
+ "Table Name": tName,
411
+ "Object Name": oName,
412
+ "Object Type": oType,
413
+ "Description": desc,
414
+ "Display Folder": display_folder,
415
+ }
416
+ result = pd.concat(
417
+ [result, pd.DataFrame(new_data, index=[0])], ignore_index=True
418
+ )
419
+ condition = (
420
+ (result["Language"] == c.Name)
421
+ & (result["Table Name"] == tName)
422
+ & (result["Object Name"] == oName)
423
+ & (result["Object Type"] == oType)
424
+ )
425
+ elif tr.Object.ObjectType == TOM.ObjectType.Hierarchy:
426
+ tName = tr.Object.Table.Name
427
+ desc = tom.model.Tables[tName].Hierarchies[oName].Description
428
+ display_folder = (
429
+ tom.model.Tables[tName].Hierarchies[oName].DisplayFolder
430
+ )
431
+ new_data = {
432
+ "Language": c.Name,
433
+ "Table Name": tName,
434
+ "Object Name": oName,
435
+ "Object Type": oType,
436
+ "Description": desc,
437
+ "Display Folder": display_folder,
438
+ }
439
+ result = pd.concat(
440
+ [result, pd.DataFrame(new_data, index=[0])], ignore_index=True
441
+ )
442
+ condition = (
443
+ (result["Language"] == c.Name)
444
+ & (result["Table Name"] == tName)
445
+ & (result["Object Name"] == oName)
446
+ & (result["Object Type"] == oType)
447
+ )
448
+
449
+ if prop == "Caption":
450
+ result.loc[condition, "Translated Object Name"] = tValue
451
+ elif prop == "Description":
452
+ result.loc[condition, "Translated Description"] = tValue
453
+ else:
454
+ result.loc[condition, "Translated Display Folder"] = tValue
455
+ result.fillna("", inplace=True)
456
+
457
+ return result