semantic-link-labs 0.4.1__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 (52) hide show
  1. semantic_link_labs-0.4.1.dist-info/LICENSE +21 -0
  2. semantic_link_labs-0.4.1.dist-info/METADATA +22 -0
  3. semantic_link_labs-0.4.1.dist-info/RECORD +52 -0
  4. semantic_link_labs-0.4.1.dist-info/WHEEL +5 -0
  5. semantic_link_labs-0.4.1.dist-info/top_level.txt +1 -0
  6. sempy_labs/__init__.py +154 -0
  7. sempy_labs/_ai.py +496 -0
  8. sempy_labs/_clear_cache.py +39 -0
  9. sempy_labs/_connections.py +234 -0
  10. sempy_labs/_dax.py +70 -0
  11. sempy_labs/_generate_semantic_model.py +280 -0
  12. sempy_labs/_helper_functions.py +506 -0
  13. sempy_labs/_icons.py +4 -0
  14. sempy_labs/_list_functions.py +1372 -0
  15. sempy_labs/_model_auto_build.py +143 -0
  16. sempy_labs/_model_bpa.py +1354 -0
  17. sempy_labs/_model_dependencies.py +341 -0
  18. sempy_labs/_one_lake_integration.py +155 -0
  19. sempy_labs/_query_scale_out.py +447 -0
  20. sempy_labs/_refresh_semantic_model.py +184 -0
  21. sempy_labs/_tom.py +3766 -0
  22. sempy_labs/_translations.py +378 -0
  23. sempy_labs/_vertipaq.py +893 -0
  24. sempy_labs/directlake/__init__.py +45 -0
  25. sempy_labs/directlake/_directlake_schema_compare.py +110 -0
  26. sempy_labs/directlake/_directlake_schema_sync.py +128 -0
  27. sempy_labs/directlake/_fallback.py +62 -0
  28. sempy_labs/directlake/_get_directlake_lakehouse.py +69 -0
  29. sempy_labs/directlake/_get_shared_expression.py +59 -0
  30. sempy_labs/directlake/_guardrails.py +84 -0
  31. sempy_labs/directlake/_list_directlake_model_calc_tables.py +54 -0
  32. sempy_labs/directlake/_show_unsupported_directlake_objects.py +89 -0
  33. sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +81 -0
  34. sempy_labs/directlake/_update_directlake_partition_entity.py +64 -0
  35. sempy_labs/directlake/_warm_cache.py +210 -0
  36. sempy_labs/lakehouse/__init__.py +24 -0
  37. sempy_labs/lakehouse/_get_lakehouse_columns.py +81 -0
  38. sempy_labs/lakehouse/_get_lakehouse_tables.py +250 -0
  39. sempy_labs/lakehouse/_lakehouse.py +85 -0
  40. sempy_labs/lakehouse/_shortcuts.py +296 -0
  41. sempy_labs/migration/__init__.py +29 -0
  42. sempy_labs/migration/_create_pqt_file.py +239 -0
  43. sempy_labs/migration/_migrate_calctables_to_lakehouse.py +429 -0
  44. sempy_labs/migration/_migrate_calctables_to_semantic_model.py +150 -0
  45. sempy_labs/migration/_migrate_model_objects_to_semantic_model.py +524 -0
  46. sempy_labs/migration/_migrate_tables_columns_to_semantic_model.py +165 -0
  47. sempy_labs/migration/_migration_validation.py +227 -0
  48. sempy_labs/migration/_refresh_calc_tables.py +129 -0
  49. sempy_labs/report/__init__.py +35 -0
  50. sempy_labs/report/_generate_report.py +253 -0
  51. sempy_labs/report/_report_functions.py +855 -0
  52. sempy_labs/report/_report_rebind.py +131 -0
sempy_labs/_ai.py ADDED
@@ -0,0 +1,496 @@
1
+ import sempy
2
+ import sempy.fabric as fabric
3
+ import pandas as pd
4
+ from synapse.ml.services.openai import OpenAICompletion
5
+ from pyspark.sql.functions import col
6
+ from pyspark.sql import SparkSession
7
+ from typing import List, Optional, Union
8
+ from IPython.display import display
9
+
10
+
11
+ def optimize_semantic_model(dataset: str, workspace: Optional[str] = None):
12
+
13
+ from ._model_bpa import run_model_bpa
14
+ from .directlake._fallback import check_fallback_reason
15
+ from ._helper_functions import format_dax_object_name
16
+
17
+ modelBPA = run_model_bpa(
18
+ dataset=dataset, workspace=workspace, return_dataframe=True
19
+ )
20
+ dfC = fabric.list_columns(dataset=dataset, workspace=workspace, extended=True)
21
+ dfC["Column Object"] = format_dax_object_name(dfC["Table Name"], dfC["Column Name"])
22
+ dfC["Total Size"] = dfC["Total Size"].astype("int")
23
+ dfP = fabric.list_partitions(dataset=dataset, workspace=workspace)
24
+
25
+ modelBPA_col = modelBPA[modelBPA["Object Type"] == "Column"]
26
+ modelBPA_col = pd.merge(
27
+ modelBPA_col,
28
+ dfC[["Column Object", "Total Size"]],
29
+ left_on="Object Name",
30
+ right_on="Column Object",
31
+ how="left",
32
+ )
33
+
34
+ isDirectLake = any(r["Mode"] == "DirectLake" for i, r in dfP.iterrows())
35
+
36
+ if isDirectLake:
37
+ fallback = check_fallback_reason(dataset=dataset, workspace=workspace)
38
+ fallback_filt = fallback[fallback["FallbackReasonID"] == 2]
39
+
40
+ if len(fallback_filt) > 0:
41
+ print(
42
+ f"The '{dataset}' semantic model is a Direct Lake semantic model which contains views. Since views always fall back to DirectQuery, it is recommended to only use lakehouse tables and not views."
43
+ )
44
+
45
+ # Potential model reduction estimate
46
+ ruleNames = [
47
+ "Remove unnecessary columns",
48
+ "Set IsAvailableInMdx to false on non-attribute columns",
49
+ ]
50
+
51
+ for rule in ruleNames:
52
+ df = modelBPA_col[modelBPA_col["Rule Name"] == rule]
53
+ df_filt = df[["Object Name", "Total Size"]].sort_values(
54
+ by="Total Size", ascending=False
55
+ )
56
+ totSize = df["Total Size"].sum()
57
+ if len(df_filt) > 0:
58
+ print(
59
+ f"Potential savings of {totSize} bytes from following the '{rule}' rule."
60
+ )
61
+ display(df_filt)
62
+ else:
63
+ print(f"The '{rule}' rule has been followed.")
64
+
65
+
66
+ def generate_measure_descriptions(
67
+ dataset: str,
68
+ measures: Union[str, List[str]],
69
+ gpt_model: Optional[str] = "gpt-35-turbo",
70
+ workspace: Optional[str] = None,
71
+ ):
72
+
73
+ service_name = "synapseml-openai"
74
+
75
+ if isinstance(measures, str):
76
+ measures = [measures]
77
+
78
+ validModels = ["gpt-35-turbo", "gpt-35-turbo-16k", "gpt-4"]
79
+ if gpt_model not in validModels:
80
+ print(
81
+ f"The '{gpt_model}' model is not a valid model. Enter a gpt_model from this list: {validModels}."
82
+ )
83
+ return
84
+
85
+ dfM = fabric.list_measures(dataset=dataset, workspace=workspace)
86
+
87
+ if measures is not None:
88
+ dfM_filt = dfM[dfM["Measure Name"].isin(measures)]
89
+ else:
90
+ dfM_filt = dfM
91
+
92
+ df = dfM_filt[["Table Name", "Measure Name", "Measure Expression"]]
93
+
94
+ df["prompt"] = (
95
+ f"The following is DAX code used by Microsoft Power BI. Please explain this code in simple terms:"
96
+ + df["Measure Expression"]
97
+ )
98
+
99
+ # Generate new column in df dataframe which has the AI-generated descriptions
100
+ completion = {
101
+ OpenAICompletion()
102
+ .setDeploymentName(gpt_model)
103
+ .setMaxTokens(200)
104
+ .setCustomServiceName(service_name)
105
+ .setPromptCol("prompt")
106
+ .setErrorCol("error")
107
+ .setOutputCol("completions")
108
+ }
109
+
110
+ completed_df = completion.transform(df).cache()
111
+ completed_df.select(
112
+ col("prompt"),
113
+ col("error"),
114
+ col("completions.choices.text").getItem(0).alias("text"),
115
+ )
116
+
117
+ # Update the model to use the new descriptions
118
+ tom_server = fabric.create_tom_server(readonly=False, workspace=workspace)
119
+ m = tom_server.Databases.GetByName(dataset).Model
120
+
121
+ # for t in m.Tables:
122
+ # tName = t.Name
123
+ # for ms in t.Measures:
124
+ # mName = ms.Name
125
+ # mDesc = promptValue
126
+
127
+ # m.SaveChanges()
128
+
129
+
130
+ def generate_aggs(
131
+ dataset: str,
132
+ table_name: str,
133
+ columns: Union[str, List[str]],
134
+ workspace: Optional[str] = None,
135
+ lakehouse_workspace: Optional[str] = None,
136
+ ):
137
+
138
+ from ._helper_functions import (
139
+ get_direct_lake_sql_endpoint,
140
+ create_abfss_path,
141
+ format_dax_object_name,
142
+ resolve_lakehouse_id,
143
+ )
144
+
145
+ sempy.fabric._client._utils._init_analysis_services()
146
+ import Microsoft.AnalysisServices.Tabular as TOM
147
+ import System
148
+
149
+ # columns = {
150
+ #'SalesAmount': 'Sum',
151
+ #'ProductKey': 'GroupBy',
152
+ #'OrderDateKey': 'GroupBy'
153
+ # }
154
+
155
+ if workspace == None:
156
+ workspace_id = fabric.get_workspace_id()
157
+ workspace = fabric.resolve_workspace_name(workspace_id)
158
+
159
+ if lakehouse_workspace == None:
160
+ lakehouse_workspace = workspace
161
+ lakehouse_workspace_id = workspace_id
162
+ else:
163
+ lakehouse_workspace_id = fabric.resolve_workspace_id(lakehouse_workspace)
164
+
165
+ if isinstance(columns, str):
166
+ columns = [columns]
167
+
168
+ columnValues = columns.keys()
169
+
170
+ aggTypes = ["Sum", "Count", "Min", "Max", "GroupBy"]
171
+ aggTypesAggregate = ["Sum", "Count", "Min", "Max"]
172
+ numericTypes = ["Int64", "Double", "Decimal"]
173
+
174
+ if any(value not in aggTypes for value in columns.values()):
175
+ print(
176
+ f"Invalid aggregation type(s) have been specified in the 'columns' parameter. Valid aggregation types: {aggTypes}."
177
+ )
178
+ return
179
+
180
+ dfC = fabric.list_columns(dataset=dataset, workspace=workspace)
181
+ dfP = fabric.list_partitions(dataset=dataset, workspace=workspace)
182
+ dfM = fabric.list_measures(dataset=dataset, workspace=workspace)
183
+ dfR = fabric.list_relationships(dataset=dataset, workspace=workspace)
184
+ if not any(r["Mode"] == "DirectLake" for i, r in dfP.iterrows()):
185
+ print(
186
+ f"The '{dataset}' semantic model within the '{workspace}' workspace is not in Direct Lake mode. This function is only relevant for Direct Lake semantic models."
187
+ )
188
+ return
189
+
190
+ dfC_filtT = dfC[dfC["Table Name"] == table_name]
191
+
192
+ if len(dfC_filtT) == 0:
193
+ print(
194
+ f"The '{table_name}' table does not exist in the '{dataset}' semantic model within the '{workspace}' workspace."
195
+ )
196
+ return
197
+
198
+ dfC_filt = dfC[
199
+ (dfC["Table Name"] == table_name) & (dfC["Column Name"].isin(columnValues))
200
+ ]
201
+
202
+ if len(columns) != len(dfC_filt):
203
+ print(
204
+ f"Columns listed in '{columnValues}' do not exist in the '{table_name}' table in the '{dataset}' semantic model within the '{workspace}' workspace."
205
+ )
206
+ return
207
+
208
+ # Check if doing sum/count/min/max etc. on a non-number column
209
+ for col, agg in columns.items():
210
+ dfC_col = dfC_filt[dfC_filt["Column Name"] == col]
211
+ dataType = dfC_col["Data Type"].iloc[0]
212
+ if agg in aggTypesAggregate and dataType not in numericTypes:
213
+ print(
214
+ f"The '{col}' column in the '{table_name}' table is of '{dataType}' data type. Only columns of '{numericTypes}' data types can be aggregated as '{aggTypesAggregate}' aggregation types."
215
+ )
216
+ return
217
+
218
+ # Create/update lakehouse delta agg table
219
+ aggSuffix = "_agg"
220
+ aggTableName = f"{table_name}{aggSuffix}"
221
+ aggLakeTName = aggTableName.lower().replace(" ", "_")
222
+ dfP = fabric.list_partitions(dataset=dataset, workspace=workspace)
223
+ dfP_filt = dfP[dfP["Table Name"] == table_name]
224
+ lakeTName = dfP_filt["Query"].iloc[0]
225
+
226
+ sqlEndpointId = get_direct_lake_sql_endpoint(dataset=dataset, workspace=workspace)
227
+
228
+ dfI = fabric.list_items(workspace=lakehouse_workspace, type="SQLEndpoint")
229
+ dfI_filt = dfI[(dfI["Id"] == sqlEndpointId)]
230
+
231
+ if len(dfI_filt) == 0:
232
+ print(
233
+ f"The lakehouse (SQL Endpoint) used by the '{dataset}' semantic model does not reside in the '{lakehouse_workspace}' workspace. Please update the lakehouse_workspace parameter."
234
+ )
235
+ return
236
+
237
+ lakehouseName = dfI_filt["Display Name"].iloc[0]
238
+ lakehouse_id = resolve_lakehouse_id(
239
+ lakehouse=lakehouseName, workspace=lakehouse_workspace
240
+ )
241
+
242
+ # Generate SQL query
243
+ query = "SELECT"
244
+ groupBy = "\nGROUP BY"
245
+ for col, agg in columns.items():
246
+ colFilt = dfC_filt[dfC_filt["Column Name"] == col]
247
+ sourceCol = colFilt["Source"].iloc[0]
248
+
249
+ if agg == "GroupBy":
250
+ query = f"{query}\n{sourceCol},"
251
+ groupBy = f"{groupBy}\n{sourceCol},"
252
+ else:
253
+ query = f"{query}\n{agg}({sourceCol}) AS {sourceCol},"
254
+
255
+ query = query[:-1]
256
+
257
+ spark = SparkSession.builder.getOrCreate()
258
+ fromTablePath = create_abfss_path(
259
+ lakehouse_id=lakehouse_id,
260
+ lakehouse_workspace_id=lakehouse_workspace_id,
261
+ delta_table_name=lakeTName,
262
+ )
263
+ df = spark.read.format("delta").load(fromTablePath)
264
+ tempTableName = "delta_table_" + lakeTName
265
+ df.createOrReplaceTempView(tempTableName)
266
+ sqlQuery = f"{query} \n FROM {tempTableName} {groupBy}"
267
+
268
+ sqlQuery = sqlQuery[:-1]
269
+ print(sqlQuery)
270
+
271
+ # Save query to spark dataframe
272
+ spark_df = spark.sql(sqlQuery)
273
+ f"\nCreating/updating the '{aggLakeTName}' table in the lakehouse..."
274
+ # Write spark dataframe to delta table
275
+ aggFilePath = create_abfss_path(
276
+ lakehouse_id=lakehouse_id,
277
+ lakehouse_workspace_id=lakehouse_workspace_id,
278
+ delta_table_name=aggLakeTName,
279
+ )
280
+ spark_df.write.mode("overwrite").format("delta").save(aggFilePath)
281
+ f"The '{aggLakeTName}' table has been created/updated in the lakehouse."
282
+
283
+ # Create/update semantic model agg table
284
+ tom_server = fabric.create_tom_server(readonly=False, workspace=workspace)
285
+ m = tom_server.Databases.GetByName(dataset).Model
286
+ f"\nUpdating the '{dataset}' semantic model..."
287
+ dfC_agg = dfC[dfC["Table Name"] == aggTableName]
288
+
289
+ if len(dfC_agg) == 0:
290
+ print(f"Creating the '{aggTableName}' table...")
291
+ exp = m.Expressions["DatabaseQuery"]
292
+ tbl = TOM.Table()
293
+ tbl.Name = aggTableName
294
+ tbl.IsHidden = True
295
+
296
+ ep = TOM.EntityPartitionSource()
297
+ ep.Name = aggTableName
298
+ ep.EntityName = aggLakeTName
299
+ ep.ExpressionSource = exp
300
+
301
+ part = TOM.Partition()
302
+ part.Name = aggTableName
303
+ part.Source = ep
304
+ part.Mode = TOM.ModeType.DirectLake
305
+
306
+ tbl.Partitions.Add(part)
307
+
308
+ for i, r in dfC_filt.iterrows():
309
+ scName = r["Source"]
310
+ cName = r["Column Name"]
311
+ dType = r["Data Type"]
312
+
313
+ col = TOM.DataColumn()
314
+ col.Name = cName
315
+ col.IsHidden = True
316
+ col.SourceColumn = scName
317
+ col.DataType = System.Enum.Parse(TOM.DataType, dType)
318
+
319
+ tbl.Columns.Add(col)
320
+ print(
321
+ f"The '{aggTableName}'[{cName}] column has been added to the '{dataset}' semantic model."
322
+ )
323
+
324
+ m.Tables.Add(tbl)
325
+ print(
326
+ f"The '{aggTableName}' table has been added to the '{dataset}' semantic model."
327
+ )
328
+ else:
329
+ print(f"Updating the '{aggTableName}' table's columns...")
330
+ # Remove existing columns
331
+ for t in m.Tables:
332
+ tName = t.Name
333
+ for c in t.Columns:
334
+ cName = c.Name
335
+ if t.Name == aggTableName:
336
+ m.Tables[tName].Columns.Remove(cName)
337
+ # Add columns
338
+ for i, r in dfC_filt.iterrows():
339
+ scName = r["Source"]
340
+ cName = r["Column Name"]
341
+ dType = r["Data Type"]
342
+
343
+ col = TOM.DataColumn()
344
+ col.Name = cName
345
+ col.IsHidden = True
346
+ col.SourceColumn = scName
347
+ col.DataType = System.Enum.Parse(TOM.DataType, dType)
348
+
349
+ m.Tables[aggTableName].Columns.Add(col)
350
+ print(f"The '{aggTableName}'[{cName}] column has been added.")
351
+
352
+ # Create relationships
353
+ relMap = {"m": "Many", "1": "One", "0": "None"}
354
+
355
+ print(f"\nGenerating necessary relationships...")
356
+ for i, r in dfR.iterrows():
357
+ fromTable = r["From Table"]
358
+ fromColumn = r["From Column"]
359
+ toTable = r["To Table"]
360
+ toColumn = r["To Column"]
361
+ cfb = r["Cross Filtering Behavior"]
362
+ sfb = r["Security Filtering Behavior"]
363
+ mult = r["Multiplicity"]
364
+
365
+ crossFB = System.Enum.Parse(TOM.CrossFilteringBehavior, cfb)
366
+ secFB = System.Enum.Parse(TOM.SecurityFilteringBehavior, sfb)
367
+ fromCardinality = System.Enum.Parse(
368
+ TOM.RelationshipEndCardinality, relMap.get(mult[0])
369
+ )
370
+ toCardinality = System.Enum.Parse(
371
+ TOM.RelationshipEndCardinality, relMap.get(mult[-1])
372
+ )
373
+
374
+ rel = TOM.SingleColumnRelationship()
375
+ rel.FromCardinality = fromCardinality
376
+ rel.ToCardinality = toCardinality
377
+ rel.IsActive = r["Active"]
378
+ rel.CrossFilteringBehavior = crossFB
379
+ rel.SecurityFilteringBehavior = secFB
380
+ rel.RelyOnReferentialIntegrity = r["Rely On Referential Integrity"]
381
+
382
+ if fromTable == table_name:
383
+ try:
384
+ rel.FromColumn = m.Tables[aggTableName].Columns[fromColumn]
385
+ m.Relationships.Add(rel)
386
+ print(
387
+ f"'{aggTableName}'[{fromColumn}] -> '{toTable}'[{toColumn}] relationship has been added."
388
+ )
389
+ except:
390
+ print(
391
+ f"'{aggTableName}'[{fromColumn}] -> '{toTable}'[{toColumn}] relationship has not been created."
392
+ )
393
+ elif toTable == table_name:
394
+ try:
395
+ rel.ToColumn = m.Tables[aggTableName].Columns[toColumn]
396
+ m.Relationships.Add(rel)
397
+ print(
398
+ f"'{fromTable}'[{fromColumn}] -> '{aggTableName}'[{toColumn}] relationship has been added."
399
+ )
400
+ except:
401
+ print(
402
+ f"'{fromTable}'[{fromColumn}] -> '{aggTableName}'[{toColumn}] relationship has not been created."
403
+ )
404
+ f"Relationship creation is complete."
405
+
406
+ # Create IF measure
407
+ f"\nCreating measure to check if the agg table can be used..."
408
+ aggChecker = "IF("
409
+ dfR_filt = dfR[
410
+ (dfR["From Table"] == table_name) & (~dfR["From Column"].isin(columnValues))
411
+ ]
412
+
413
+ for i, r in dfR_filt.iterrows():
414
+ toTable = r["To Table"]
415
+ aggChecker = f"{aggChecker}\nISCROSSFILTERED('{toTable}') ||"
416
+
417
+ aggChecker = aggChecker[:-3]
418
+ aggChecker = f"{aggChecker},1,0)"
419
+ print(aggChecker)
420
+
421
+ # Todo: add IFISFILTERED clause for columns
422
+ f"\n Creating the base measures in the agg table..."
423
+ # Create base agg measures
424
+ dep = fabric.evaluate_dax(
425
+ dataset=dataset,
426
+ workspace=workspace,
427
+ dax_string="""
428
+ SELECT
429
+ [TABLE] AS [Table Name]
430
+ ,[OBJECT] AS [Object Name]
431
+ ,[OBJECT_TYPE] AS [Object Type]
432
+ ,[REFERENCED_TABLE] AS [Referenced Table]
433
+ ,[REFERENCED_OBJECT] AS [Referenced Object]
434
+ ,[REFERENCED_OBJECT_TYPE] AS [Referenced Object Type]
435
+ FROM $SYSTEM.DISCOVER_CALC_DEPENDENCY
436
+ WHERE [OBJECT_TYPE] = 'MEASURE'
437
+ """,
438
+ )
439
+
440
+ baseMeasures = dep[
441
+ (dep["Referenced Object Type"] == "COLUMN")
442
+ & (dep["Referenced Table"] == table_name)
443
+ & (dep["Referenced Object"].isin(columnValues))
444
+ ]
445
+ for i, r in baseMeasures.iterrows():
446
+ tName = r["Table Name"]
447
+ mName = r["Object Name"]
448
+ cName = r["Referenced Object"]
449
+ dfM_filt = dfM[dfM["Measure Name"] == mName]
450
+ expr = dfM_filt["Measure Expression"].iloc[0]
451
+
452
+ colFQNonAgg = format_dax_object_name(tName, cName)
453
+ colFQAgg = format_dax_object_name(aggTableName, cName)
454
+ colNQNonAgg = f"{tName}[{cName}]"
455
+
456
+ if " " in tName:
457
+ newExpr = expr.replace(colFQNonAgg, colFQAgg)
458
+ else:
459
+ newExpr = expr.replace(colFQNonAgg, colFQAgg).replace(colNQNonAgg, colFQAgg)
460
+ print(expr)
461
+ print(newExpr)
462
+
463
+ aggMName = mName + aggSuffix
464
+ measure = TOM.Measure()
465
+ measure.Name = aggMName
466
+ measure.IsHidden = True
467
+ measure.Expression = newExpr
468
+ m.Tables[aggTableName].Measures.Add(measure)
469
+ f"The '{aggMName}' measure has been created in the '{aggTableName}' table."
470
+
471
+ # Update base detail measures
472
+
473
+ # m.SaveChanges()
474
+
475
+
476
+ # Identify views used within Direct Lake model
477
+ # workspace = 'MK Demo 6'
478
+ # lakehouse = 'MyLakehouse'
479
+ # dataset = 'MigrationTest'
480
+ # lakehouse_workspace = workspace
481
+
482
+ # dfView = pd.DataFrame(columns=['Workspace Name', 'Lakehouse Name', 'View Name'])
483
+ # dfP = fabric.list_partitions(dataset = dataset, workspace = workspace)
484
+ # isDirectLake = any(r['Mode'] == 'DirectLake' for i, r in dfP.iterrows())
485
+
486
+ # spark = SparkSession.builder.getOrCreate()
487
+ # views = spark.sql(f"SHOW VIEWS IN {lakehouse}").collect()
488
+ # for view in views:
489
+ # viewName = view['viewName']
490
+ # isTemporary = view['isTemporary']
491
+ # new_data = {'Workspace Name': workspace, 'Lakehouse Name': lakehouse, 'View Name': viewName}
492
+ # dfView = pd.concat([dfView, pd.DataFrame(new_data, index=[0])], ignore_index=True)
493
+ # dfView
494
+ # lakeT = get_lakehouse_tables(lakehouse, lakehouse_workspace)
495
+ # if not dfP['Query'].isin(lakeT['Table Name'].values):
496
+ # if
@@ -0,0 +1,39 @@
1
+ import sempy
2
+ import sempy.fabric as fabric
3
+ from ._helper_functions import resolve_dataset_id
4
+ from typing import List, Optional, Union
5
+ import sempy_labs._icons as icons
6
+
7
+
8
+ def clear_cache(dataset: str, workspace: Optional[str] = None):
9
+ """
10
+ Clears the cache of a semantic model.
11
+
12
+ Parameters
13
+ ----------
14
+ dataset : str
15
+ Name of the semantic model.
16
+ workspace : str, default=None
17
+ The Fabric workspace name.
18
+ Defaults to None which resolves to the workspace of the attached lakehouse
19
+ or if no lakehouse attached, resolves to the workspace of the notebook.
20
+ """
21
+
22
+ if workspace == None:
23
+ workspace_id = fabric.get_workspace_id()
24
+ workspace = fabric.resolve_workspace_name(workspace_id)
25
+
26
+ datasetID = resolve_dataset_id(dataset=dataset, workspace=workspace)
27
+
28
+ xmla = f"""
29
+ <ClearCache xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">
30
+ <Object>
31
+ <DatabaseID>{datasetID}</DatabaseID>
32
+ </Object>
33
+ </ClearCache>
34
+ """
35
+ fabric.execute_xmla(dataset=dataset, xmla_command=xmla, workspace=workspace)
36
+
37
+ outputtext = f"{icons.green_dot} Cache cleared for the '{dataset}' semantic model within the '{workspace}' workspace."
38
+
39
+ return outputtext