semantic-link-labs 0.8.10__py3-none-any.whl → 0.8.11__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.
- {semantic_link_labs-0.8.10.dist-info → semantic_link_labs-0.8.11.dist-info}/METADATA +3 -2
- {semantic_link_labs-0.8.10.dist-info → semantic_link_labs-0.8.11.dist-info}/RECORD +73 -72
- sempy_labs/__init__.py +6 -2
- sempy_labs/_clear_cache.py +39 -37
- sempy_labs/_connections.py +13 -13
- sempy_labs/_data_pipelines.py +20 -20
- sempy_labs/_dataflows.py +27 -28
- sempy_labs/_dax.py +41 -47
- sempy_labs/_environments.py +26 -23
- sempy_labs/_eventhouses.py +16 -15
- sempy_labs/_eventstreams.py +16 -15
- sempy_labs/_external_data_shares.py +18 -20
- sempy_labs/_gateways.py +14 -14
- sempy_labs/_generate_semantic_model.py +99 -62
- sempy_labs/_git.py +105 -43
- sempy_labs/_helper_functions.py +148 -131
- sempy_labs/_job_scheduler.py +92 -0
- sempy_labs/_kql_databases.py +16 -15
- sempy_labs/_kql_querysets.py +16 -15
- sempy_labs/_list_functions.py +114 -99
- sempy_labs/_managed_private_endpoints.py +19 -17
- sempy_labs/_mirrored_databases.py +51 -48
- sempy_labs/_mirrored_warehouses.py +5 -4
- sempy_labs/_ml_experiments.py +16 -15
- sempy_labs/_ml_models.py +15 -14
- sempy_labs/_model_bpa.py +3 -3
- sempy_labs/_model_dependencies.py +55 -29
- sempy_labs/_notebooks.py +27 -25
- sempy_labs/_one_lake_integration.py +23 -26
- sempy_labs/_query_scale_out.py +67 -64
- sempy_labs/_refresh_semantic_model.py +25 -26
- sempy_labs/_spark.py +33 -32
- sempy_labs/_sql.py +12 -9
- sempy_labs/_translations.py +10 -7
- sempy_labs/_vertipaq.py +34 -31
- sempy_labs/_warehouses.py +22 -21
- sempy_labs/_workspace_identity.py +11 -10
- sempy_labs/_workspaces.py +40 -33
- sempy_labs/admin/_basic_functions.py +10 -12
- sempy_labs/admin/_external_data_share.py +3 -3
- sempy_labs/admin/_items.py +4 -4
- sempy_labs/admin/_scanner.py +3 -1
- sempy_labs/directlake/_directlake_schema_compare.py +18 -14
- sempy_labs/directlake/_directlake_schema_sync.py +18 -12
- sempy_labs/directlake/_dl_helper.py +25 -26
- sempy_labs/directlake/_generate_shared_expression.py +10 -9
- sempy_labs/directlake/_get_directlake_lakehouse.py +16 -13
- sempy_labs/directlake/_get_shared_expression.py +4 -3
- sempy_labs/directlake/_guardrails.py +12 -6
- sempy_labs/directlake/_list_directlake_model_calc_tables.py +15 -9
- sempy_labs/directlake/_show_unsupported_directlake_objects.py +16 -10
- sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +35 -31
- sempy_labs/directlake/_update_directlake_partition_entity.py +34 -31
- sempy_labs/directlake/_warm_cache.py +87 -65
- sempy_labs/lakehouse/_get_lakehouse_columns.py +10 -8
- sempy_labs/lakehouse/_get_lakehouse_tables.py +10 -9
- sempy_labs/lakehouse/_lakehouse.py +17 -13
- sempy_labs/lakehouse/_shortcuts.py +42 -23
- sempy_labs/migration/_create_pqt_file.py +16 -11
- sempy_labs/migration/_refresh_calc_tables.py +16 -10
- sempy_labs/report/_download_report.py +9 -8
- sempy_labs/report/_generate_report.py +40 -44
- sempy_labs/report/_paginated.py +9 -9
- sempy_labs/report/_report_bpa.py +13 -9
- sempy_labs/report/_report_functions.py +80 -91
- sempy_labs/report/_report_helper.py +8 -4
- sempy_labs/report/_report_list_functions.py +24 -13
- sempy_labs/report/_report_rebind.py +17 -16
- sempy_labs/report/_reportwrapper.py +41 -33
- sempy_labs/tom/_model.py +43 -6
- {semantic_link_labs-0.8.10.dist-info → semantic_link_labs-0.8.11.dist-info}/LICENSE +0 -0
- {semantic_link_labs-0.8.10.dist-info → semantic_link_labs-0.8.11.dist-info}/WHEEL +0 -0
- {semantic_link_labs-0.8.10.dist-info → semantic_link_labs-0.8.11.dist-info}/top_level.txt +0 -0
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import sempy.fabric as fabric
|
|
2
2
|
from sempy_labs._helper_functions import (
|
|
3
3
|
resolve_dataset_id,
|
|
4
|
+
resolve_workspace_name_and_id,
|
|
4
5
|
resolve_report_id,
|
|
5
6
|
)
|
|
6
7
|
from typing import Optional, List
|
|
7
8
|
from sempy._utils._log import log
|
|
8
9
|
import sempy_labs._icons as icons
|
|
9
10
|
from sempy.fabric.exceptions import FabricHTTPException
|
|
11
|
+
from uuid import UUID
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
@log
|
|
13
15
|
def report_rebind(
|
|
14
16
|
report: str | List[str],
|
|
15
17
|
dataset: str,
|
|
16
|
-
report_workspace: Optional[str] = None,
|
|
17
|
-
dataset_workspace: Optional[str] = None,
|
|
18
|
+
report_workspace: Optional[str | UUID] = None,
|
|
19
|
+
dataset_workspace: Optional[str | UUID] = None,
|
|
18
20
|
):
|
|
19
21
|
"""
|
|
20
22
|
Rebinds a report to a semantic model.
|
|
@@ -27,23 +29,22 @@ def report_rebind(
|
|
|
27
29
|
Name(s) of the Power BI report(s).
|
|
28
30
|
dataset : str
|
|
29
31
|
Name of the semantic model.
|
|
30
|
-
report_workspace : str, default=None
|
|
31
|
-
The name of the Fabric workspace in which the report resides.
|
|
32
|
+
report_workspace : str | uuid.UUID, default=None
|
|
33
|
+
The name or ID of the Fabric workspace in which the report resides.
|
|
32
34
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
33
35
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
34
|
-
dataset_workspace : str, default=None
|
|
35
|
-
The name of the Fabric workspace in which the semantic model resides.
|
|
36
|
+
dataset_workspace : str | uuid.UUID, default=None
|
|
37
|
+
The name or ID of the Fabric workspace in which the semantic model resides.
|
|
36
38
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
37
39
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
38
40
|
"""
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
report_workspace_id = fabric.resolve_workspace_id(report_workspace)
|
|
42
|
+
(report_workspace_name, report_workspace_id) = resolve_workspace_name_and_id(
|
|
43
|
+
report_workspace
|
|
44
|
+
)
|
|
45
|
+
|
|
45
46
|
if dataset_workspace is None:
|
|
46
|
-
dataset_workspace =
|
|
47
|
+
dataset_workspace = report_workspace_name
|
|
47
48
|
|
|
48
49
|
client = fabric.PowerBIRestClient()
|
|
49
50
|
|
|
@@ -51,14 +52,14 @@ def report_rebind(
|
|
|
51
52
|
report = [report]
|
|
52
53
|
|
|
53
54
|
for rpt in report:
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
report_id = resolve_report_id(report=rpt, workspace=report_workspace_id)
|
|
56
|
+
dataset_id = resolve_dataset_id(dataset=dataset, workspace=dataset_workspace)
|
|
56
57
|
|
|
57
58
|
# Prepare API
|
|
58
|
-
request_body = {"datasetId":
|
|
59
|
+
request_body = {"datasetId": dataset_id}
|
|
59
60
|
|
|
60
61
|
response = client.post(
|
|
61
|
-
f"/v1.0/myorg/groups/{report_workspace_id}/reports/{
|
|
62
|
+
f"/v1.0/myorg/groups/{report_workspace_id}/reports/{report_id}/Rebind",
|
|
62
63
|
json=request_body,
|
|
63
64
|
)
|
|
64
65
|
|
|
@@ -8,6 +8,7 @@ from sempy_labs._helper_functions import (
|
|
|
8
8
|
_add_part,
|
|
9
9
|
lro,
|
|
10
10
|
_decode_b64,
|
|
11
|
+
resolve_workspace_name_and_id,
|
|
11
12
|
)
|
|
12
13
|
from typing import Optional, List
|
|
13
14
|
import pandas as pd
|
|
@@ -32,8 +33,8 @@ class ReportWrapper:
|
|
|
32
33
|
----------
|
|
33
34
|
report : str
|
|
34
35
|
The name of the report.
|
|
35
|
-
workspace : str
|
|
36
|
-
The name of the workspace in which the report resides.
|
|
36
|
+
workspace : str | uuid.UUID
|
|
37
|
+
The name or ID of the workspace in which the report resides.
|
|
37
38
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
38
39
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
39
40
|
|
|
@@ -50,7 +51,7 @@ class ReportWrapper:
|
|
|
50
51
|
def __init__(
|
|
51
52
|
self,
|
|
52
53
|
report: str,
|
|
53
|
-
workspace: Optional[str] = None,
|
|
54
|
+
workspace: Optional[str | UUID] = None,
|
|
54
55
|
):
|
|
55
56
|
"""
|
|
56
57
|
Connects to a Power BI report and retrieves its definition.
|
|
@@ -61,8 +62,8 @@ class ReportWrapper:
|
|
|
61
62
|
----------
|
|
62
63
|
report : str
|
|
63
64
|
The name of the report.
|
|
64
|
-
workspace : str
|
|
65
|
-
The name of the workspace in which the report resides.
|
|
65
|
+
workspace : str | UUID
|
|
66
|
+
The name or ID of the workspace in which the report resides.
|
|
66
67
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
67
68
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
68
69
|
|
|
@@ -77,11 +78,12 @@ class ReportWrapper:
|
|
|
77
78
|
warnings.simplefilter(action="ignore", category=FutureWarning)
|
|
78
79
|
|
|
79
80
|
self._report = report
|
|
80
|
-
self.
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
(self._workspace_name, self._workspace_id) = resolve_workspace_name_and_id(
|
|
82
|
+
workspace
|
|
83
|
+
)
|
|
84
|
+
self._report_id = resolve_report_id(report, self._workspace_id)
|
|
83
85
|
self.rdef = get_report_definition(
|
|
84
|
-
report=self._report, workspace=self.
|
|
86
|
+
report=self._report, workspace=self._workspace_id
|
|
85
87
|
)
|
|
86
88
|
|
|
87
89
|
if len(self.rdef[self.rdef["path"] == "definition/report.json"]) == 0:
|
|
@@ -95,12 +97,14 @@ class ReportWrapper:
|
|
|
95
97
|
|
|
96
98
|
from sempy_labs.tom import connect_semantic_model
|
|
97
99
|
|
|
98
|
-
dataset_id, dataset_name, dataset_workspace_id,
|
|
99
|
-
resolve_dataset_from_report(
|
|
100
|
+
dataset_id, dataset_name, dataset_workspace_id, dataset_workspace_name = (
|
|
101
|
+
resolve_dataset_from_report(
|
|
102
|
+
report=self._report, workspace=self._workspace_id
|
|
103
|
+
)
|
|
100
104
|
)
|
|
101
105
|
|
|
102
106
|
with connect_semantic_model(
|
|
103
|
-
dataset=
|
|
107
|
+
dataset=dataset_id, readonly=True, workspace=dataset_workspace_id
|
|
104
108
|
) as tom:
|
|
105
109
|
for index, row in dataframe.iterrows():
|
|
106
110
|
obj_type = row["Object Type"]
|
|
@@ -218,7 +222,7 @@ class ReportWrapper:
|
|
|
218
222
|
theme_collection = rptJson.get("themeCollection", {})
|
|
219
223
|
if theme_type not in theme_collection:
|
|
220
224
|
raise ValueError(
|
|
221
|
-
f"{icons.red_dot} The {self._report} report within the '{self.
|
|
225
|
+
f"{icons.red_dot} The {self._report} report within the '{self._workspace_name} workspace has no custom theme."
|
|
222
226
|
)
|
|
223
227
|
ct = theme_collection.get(theme_type)
|
|
224
228
|
theme_name = ct["name"]
|
|
@@ -413,7 +417,7 @@ class ReportWrapper:
|
|
|
413
417
|
)
|
|
414
418
|
|
|
415
419
|
df["Page URL"] = df["Page Name"].apply(
|
|
416
|
-
lambda page_name: f"{helper.get_web_url(report=self._report, workspace=self.
|
|
420
|
+
lambda page_name: f"{helper.get_web_url(report=self._report, workspace=self._workspace_id)}/{page_name}"
|
|
417
421
|
)
|
|
418
422
|
|
|
419
423
|
bool_cols = ["Hidden", "Locked", "Used"]
|
|
@@ -691,7 +695,7 @@ class ReportWrapper:
|
|
|
691
695
|
df[bool_cols] = df[bool_cols].astype(bool)
|
|
692
696
|
|
|
693
697
|
df["Page URL"] = df["Page Name"].apply(
|
|
694
|
-
lambda page_name: f"{helper.get_web_url(report=self._report, workspace=self.
|
|
698
|
+
lambda page_name: f"{helper.get_web_url(report=self._report, workspace=self._workspace_id)}/{page_name}"
|
|
695
699
|
)
|
|
696
700
|
|
|
697
701
|
return df
|
|
@@ -1170,9 +1174,9 @@ class ReportWrapper:
|
|
|
1170
1174
|
)
|
|
1171
1175
|
|
|
1172
1176
|
if extended:
|
|
1173
|
-
dataset_id, dataset_name, dataset_workspace_id,
|
|
1177
|
+
dataset_id, dataset_name, dataset_workspace_id, dataset_workspace_name = (
|
|
1174
1178
|
resolve_dataset_from_report(
|
|
1175
|
-
report=self._report, workspace=self.
|
|
1179
|
+
report=self._report, workspace=self._workspace_id
|
|
1176
1180
|
)
|
|
1177
1181
|
)
|
|
1178
1182
|
|
|
@@ -1195,7 +1199,7 @@ class ReportWrapper:
|
|
|
1195
1199
|
return object_validators.get(row["Object Type"], lambda: False)()
|
|
1196
1200
|
|
|
1197
1201
|
with connect_semantic_model(
|
|
1198
|
-
dataset=
|
|
1202
|
+
dataset=dataset_id, readonly=True, workspace=dataset_workspace_id
|
|
1199
1203
|
) as tom:
|
|
1200
1204
|
df["Valid Semantic Model Object"] = df.apply(
|
|
1201
1205
|
lambda row: check_validity(tom, row), axis=1
|
|
@@ -1214,11 +1218,13 @@ class ReportWrapper:
|
|
|
1214
1218
|
.drop_duplicates()
|
|
1215
1219
|
.reset_index(drop=True)
|
|
1216
1220
|
)
|
|
1217
|
-
dataset_id, dataset_name, dataset_workspace_id,
|
|
1218
|
-
resolve_dataset_from_report(
|
|
1221
|
+
dataset_id, dataset_name, dataset_workspace_id, dataset_workspace_name = (
|
|
1222
|
+
resolve_dataset_from_report(
|
|
1223
|
+
report=self._report, workspace=self._workspace_id
|
|
1224
|
+
)
|
|
1219
1225
|
)
|
|
1220
1226
|
dep = get_measure_dependencies(
|
|
1221
|
-
dataset=
|
|
1227
|
+
dataset=dataset_id, workspace=dataset_workspace_id
|
|
1222
1228
|
)
|
|
1223
1229
|
rpt_measures = df[df["Object Type"] == "Measure"]["Object Name"].values
|
|
1224
1230
|
new_rows = dep[dep["Object Name"].isin(rpt_measures)][
|
|
@@ -1232,7 +1238,7 @@ class ReportWrapper:
|
|
|
1232
1238
|
)
|
|
1233
1239
|
|
|
1234
1240
|
result_df["Dataset Name"] = dataset_name
|
|
1235
|
-
result_df["Dataset Workspace Name"] =
|
|
1241
|
+
result_df["Dataset Workspace Name"] = dataset_workspace_name
|
|
1236
1242
|
colName = "Dataset Name"
|
|
1237
1243
|
result_df.insert(0, colName, result_df.pop(colName))
|
|
1238
1244
|
colName = "Dataset Workspace Name"
|
|
@@ -1539,7 +1545,7 @@ class ReportWrapper:
|
|
|
1539
1545
|
|
|
1540
1546
|
self.update_report(request_body=request_body)
|
|
1541
1547
|
print(
|
|
1542
|
-
f"{icons.green_dot} The '{theme_name}' theme has been set as the theme for the '{self._report}' report within the '{self.
|
|
1548
|
+
f"{icons.green_dot} The '{theme_name}' theme has been set as the theme for the '{self._report}' report within the '{self._workspace_name}' workspace."
|
|
1543
1549
|
)
|
|
1544
1550
|
|
|
1545
1551
|
def set_active_page(self, page_name: str):
|
|
@@ -1567,7 +1573,7 @@ class ReportWrapper:
|
|
|
1567
1573
|
self._update_single_file(file_name=pages_file, new_payload=file_payload)
|
|
1568
1574
|
|
|
1569
1575
|
print(
|
|
1570
|
-
f"{icons.green_dot} The '{page_display_name}' page has been set as the active page in the '{self._report}' report within the '{self.
|
|
1576
|
+
f"{icons.green_dot} The '{page_display_name}' page has been set as the active page in the '{self._report}' report within the '{self._workspace_name}' workspace."
|
|
1571
1577
|
)
|
|
1572
1578
|
|
|
1573
1579
|
def set_page_type(self, page_name: str, page_type: str):
|
|
@@ -1640,7 +1646,7 @@ class ReportWrapper:
|
|
|
1640
1646
|
cv_remove_display.append(cv_display)
|
|
1641
1647
|
if len(cv_remove) == 0:
|
|
1642
1648
|
print(
|
|
1643
|
-
f"{icons.green_dot} There are no unnecessary custom visuals in the '{self._report}' report within the '{self.
|
|
1649
|
+
f"{icons.green_dot} There are no unnecessary custom visuals in the '{self._report}' report within the '{self._workspace_name}' workspace."
|
|
1644
1650
|
)
|
|
1645
1651
|
return
|
|
1646
1652
|
|
|
@@ -1662,7 +1668,7 @@ class ReportWrapper:
|
|
|
1662
1668
|
|
|
1663
1669
|
self.update_report(request_body=request_body)
|
|
1664
1670
|
print(
|
|
1665
|
-
f"{icons.green_dot} The {cv_remove_display} custom visuals have been removed from the '{self._report}' report within the '{self.
|
|
1671
|
+
f"{icons.green_dot} The {cv_remove_display} custom visuals have been removed from the '{self._report}' report within the '{self._workspace_name}' workspace."
|
|
1666
1672
|
)
|
|
1667
1673
|
|
|
1668
1674
|
def migrate_report_level_measures(self, measures: Optional[str | List[str]] = None):
|
|
@@ -1681,12 +1687,14 @@ class ReportWrapper:
|
|
|
1681
1687
|
rlm = self.list_report_level_measures()
|
|
1682
1688
|
if len(rlm) == 0:
|
|
1683
1689
|
print(
|
|
1684
|
-
f"{icons.green_dot} The '{self._report}' report within the '{self.
|
|
1690
|
+
f"{icons.green_dot} The '{self._report}' report within the '{self._workspace_name}' workspace has no report-level measures."
|
|
1685
1691
|
)
|
|
1686
1692
|
return
|
|
1687
1693
|
|
|
1688
|
-
dataset_id, dataset_name, dataset_workspace_id,
|
|
1689
|
-
resolve_dataset_from_report(
|
|
1694
|
+
dataset_id, dataset_name, dataset_workspace_id, dataset_workspace_name = (
|
|
1695
|
+
resolve_dataset_from_report(
|
|
1696
|
+
report=self._report, workspace=self._workspace_id
|
|
1697
|
+
)
|
|
1690
1698
|
)
|
|
1691
1699
|
|
|
1692
1700
|
if isinstance(measures, str):
|
|
@@ -1703,7 +1711,7 @@ class ReportWrapper:
|
|
|
1703
1711
|
|
|
1704
1712
|
mCount = 0
|
|
1705
1713
|
with connect_semantic_model(
|
|
1706
|
-
dataset=
|
|
1714
|
+
dataset=dataset_id, readonly=False, workspace=dataset_workspace_id
|
|
1707
1715
|
) as tom:
|
|
1708
1716
|
for _, r in rlm.iterrows():
|
|
1709
1717
|
tableName = r["Table Name"]
|
|
@@ -1748,7 +1756,7 @@ class ReportWrapper:
|
|
|
1748
1756
|
|
|
1749
1757
|
self.update_report(request_body=request_body)
|
|
1750
1758
|
print(
|
|
1751
|
-
f"{icons.green_dot} The report-level measures have been migrated to the '{dataset_name}' semantic model within the '{
|
|
1759
|
+
f"{icons.green_dot} The report-level measures have been migrated to the '{dataset_name}' semantic model within the '{dataset_workspace_name}' workspace."
|
|
1752
1760
|
)
|
|
1753
1761
|
|
|
1754
1762
|
def set_page_visibility(self, page_name: str, hidden: bool):
|
|
@@ -1798,7 +1806,7 @@ class ReportWrapper:
|
|
|
1798
1806
|
|
|
1799
1807
|
if len(dfP_filt) == 0:
|
|
1800
1808
|
print(
|
|
1801
|
-
f"{icons.green_dot} There are no Tooltip or Drillthrough pages in the '{self._report}' report within the '{self.
|
|
1809
|
+
f"{icons.green_dot} There are no Tooltip or Drillthrough pages in the '{self._report}' report within the '{self._workspace_name}' workspace."
|
|
1802
1810
|
)
|
|
1803
1811
|
return
|
|
1804
1812
|
|
|
@@ -1837,7 +1845,7 @@ class ReportWrapper:
|
|
|
1837
1845
|
|
|
1838
1846
|
self.update_report(request_body=request_body)
|
|
1839
1847
|
print(
|
|
1840
|
-
f"{icons.green_dot} Show items with data has been disabled for all visuals in the '{self._report}' report within the '{self.
|
|
1848
|
+
f"{icons.green_dot} Show items with data has been disabled for all visuals in the '{self._report}' report within the '{self._workspace_name}' workspace."
|
|
1841
1849
|
)
|
|
1842
1850
|
|
|
1843
1851
|
# Set Annotations
|
sempy_labs/tom/_model.py
CHANGED
|
@@ -3287,6 +3287,10 @@ class TOMWrapper:
|
|
|
3287
3287
|
"""
|
|
3288
3288
|
import Microsoft.AnalysisServices.Tabular as TOM
|
|
3289
3289
|
|
|
3290
|
+
dependencies = dependencies[
|
|
3291
|
+
dependencies["Object Name"] == dependencies["Parent Node"]
|
|
3292
|
+
]
|
|
3293
|
+
|
|
3290
3294
|
for obj in self.depends_on(object=object, dependencies=dependencies):
|
|
3291
3295
|
if obj.ObjectType == TOM.ObjectType.Measure:
|
|
3292
3296
|
if (f"{obj.Parent.Name}[{obj.Name}]" in object.Expression) or (
|
|
@@ -3313,12 +3317,16 @@ class TOMWrapper:
|
|
|
3313
3317
|
"""
|
|
3314
3318
|
import Microsoft.AnalysisServices.Tabular as TOM
|
|
3315
3319
|
|
|
3320
|
+
dependencies = dependencies[
|
|
3321
|
+
dependencies["Object Name"] == dependencies["Parent Node"]
|
|
3322
|
+
]
|
|
3323
|
+
|
|
3316
3324
|
def create_pattern(tableList, b):
|
|
3317
3325
|
patterns = [
|
|
3318
|
-
r"(?<!" + re.escape(table) + r"
|
|
3326
|
+
r"(?<!" + re.escape(table) + r")(?<!'" + re.escape(table) + r"')"
|
|
3319
3327
|
for table in tableList
|
|
3320
3328
|
]
|
|
3321
|
-
combined_pattern = "".join(patterns) + re.escape(b)
|
|
3329
|
+
combined_pattern = "".join(patterns) + re.escape(f"[{b}]")
|
|
3322
3330
|
return combined_pattern
|
|
3323
3331
|
|
|
3324
3332
|
for obj in self.depends_on(object=object, dependencies=dependencies):
|
|
@@ -4529,7 +4537,7 @@ class TOMWrapper:
|
|
|
4529
4537
|
|
|
4530
4538
|
def add_role_member(self, role_name: str, member: str | List[str]):
|
|
4531
4539
|
"""
|
|
4532
|
-
Adds
|
|
4540
|
+
Adds an external model role member (AzureAD) to a role.
|
|
4533
4541
|
|
|
4534
4542
|
Parameters
|
|
4535
4543
|
----------
|
|
@@ -4561,6 +4569,35 @@ class TOMWrapper:
|
|
|
4561
4569
|
f"{icons.yellow_dot} '{m}' is already a member in the '{role_name}' role."
|
|
4562
4570
|
)
|
|
4563
4571
|
|
|
4572
|
+
def remove_role_member(self, role_name: str, member: str | List[str]):
|
|
4573
|
+
"""
|
|
4574
|
+
Removes an external model role member (AzureAD) from a role.
|
|
4575
|
+
|
|
4576
|
+
Parameters
|
|
4577
|
+
----------
|
|
4578
|
+
role_name : str
|
|
4579
|
+
The role name.
|
|
4580
|
+
member : str | List[str]
|
|
4581
|
+
The email address(es) of the member(s) to remove.
|
|
4582
|
+
"""
|
|
4583
|
+
|
|
4584
|
+
if isinstance(member, str):
|
|
4585
|
+
member = [member]
|
|
4586
|
+
|
|
4587
|
+
role = self.model.Roles[role_name]
|
|
4588
|
+
current_members = {m.MemberName: m.Name for m in role.Members}
|
|
4589
|
+
for m in member:
|
|
4590
|
+
name = current_members.get(m)
|
|
4591
|
+
if name is not None:
|
|
4592
|
+
role.Members.Remove(role.Members[name])
|
|
4593
|
+
print(
|
|
4594
|
+
f"{icons.green_dot} The '{m}' member has been removed from the '{role_name}' role."
|
|
4595
|
+
)
|
|
4596
|
+
else:
|
|
4597
|
+
print(
|
|
4598
|
+
f"{icons.yellow_dot} '{m}' is not a member of the '{role_name}' role."
|
|
4599
|
+
)
|
|
4600
|
+
|
|
4564
4601
|
def close(self):
|
|
4565
4602
|
|
|
4566
4603
|
if not self._readonly and self.model is not None:
|
|
@@ -4637,12 +4674,12 @@ def connect_semantic_model(
|
|
|
4637
4674
|
|
|
4638
4675
|
Parameters
|
|
4639
4676
|
----------
|
|
4640
|
-
dataset : str | UUID
|
|
4677
|
+
dataset : str | uuid.UUID
|
|
4641
4678
|
Name or ID of the semantic model.
|
|
4642
4679
|
readonly: bool, default=True
|
|
4643
4680
|
Whether the connection is read-only or read/write. Setting this to False enables read/write which saves the changes made back to the server.
|
|
4644
|
-
workspace : str, default=None
|
|
4645
|
-
The Fabric workspace name.
|
|
4681
|
+
workspace : str | uuid.UUID, default=None
|
|
4682
|
+
The Fabric workspace name or ID.
|
|
4646
4683
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
4647
4684
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
4648
4685
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|