semantic-link-labs 0.9.4__py3-none-any.whl → 0.9.6__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.9.4.dist-info → semantic_link_labs-0.9.6.dist-info}/METADATA +19 -2
- {semantic_link_labs-0.9.4.dist-info → semantic_link_labs-0.9.6.dist-info}/RECORD +71 -64
- {semantic_link_labs-0.9.4.dist-info → semantic_link_labs-0.9.6.dist-info}/WHEEL +1 -1
- sempy_labs/__init__.py +33 -4
- sempy_labs/_capacities.py +59 -128
- sempy_labs/_capacity_migration.py +19 -21
- sempy_labs/_connections.py +2 -4
- sempy_labs/_dashboards.py +60 -0
- sempy_labs/_data_pipelines.py +5 -31
- sempy_labs/_dataflows.py +2 -2
- sempy_labs/_dax_query_view.py +55 -0
- sempy_labs/_delta_analyzer.py +16 -14
- sempy_labs/_environments.py +28 -49
- sempy_labs/_eventhouses.py +27 -53
- sempy_labs/_eventstreams.py +16 -34
- sempy_labs/_external_data_shares.py +4 -10
- sempy_labs/_gateways.py +4 -4
- sempy_labs/_generate_semantic_model.py +2 -2
- sempy_labs/_git.py +90 -1
- sempy_labs/_graphQL.py +8 -21
- sempy_labs/_helper_functions.py +440 -91
- sempy_labs/_kql_databases.py +24 -35
- sempy_labs/_kql_querysets.py +15 -32
- sempy_labs/_list_functions.py +17 -192
- sempy_labs/_managed_private_endpoints.py +9 -2
- sempy_labs/_mirrored_databases.py +17 -49
- sempy_labs/_ml_experiments.py +6 -31
- sempy_labs/_ml_models.py +4 -28
- sempy_labs/_model_bpa.py +4 -11
- sempy_labs/_model_bpa_bulk.py +23 -27
- sempy_labs/_mounted_data_factories.py +119 -0
- sempy_labs/_notebooks.py +16 -26
- sempy_labs/_one_lake_integration.py +2 -1
- sempy_labs/_semantic_models.py +20 -0
- sempy_labs/_sql.py +13 -8
- sempy_labs/_sqldatabase.py +61 -100
- sempy_labs/_utils.py +42 -0
- sempy_labs/_vertipaq.py +25 -13
- sempy_labs/_warehouses.py +19 -20
- sempy_labs/_workloads.py +23 -9
- sempy_labs/_workspace_identity.py +6 -0
- sempy_labs/_workspaces.py +55 -7
- sempy_labs/admin/__init__.py +21 -1
- sempy_labs/admin/_apps.py +1 -1
- sempy_labs/admin/_artifacts.py +62 -0
- sempy_labs/admin/_basic_functions.py +3 -54
- sempy_labs/admin/_capacities.py +61 -0
- sempy_labs/admin/_reports.py +74 -0
- sempy_labs/admin/_scanner.py +2 -2
- sempy_labs/admin/_shared.py +4 -2
- sempy_labs/admin/_users.py +133 -0
- sempy_labs/admin/_workspaces.py +148 -0
- sempy_labs/directlake/_directlake_schema_compare.py +2 -1
- sempy_labs/directlake/_directlake_schema_sync.py +65 -19
- sempy_labs/directlake/_dl_helper.py +0 -6
- sempy_labs/directlake/_generate_shared_expression.py +10 -11
- sempy_labs/directlake/_guardrails.py +2 -1
- sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py +12 -25
- sempy_labs/directlake/_update_directlake_partition_entity.py +11 -3
- sempy_labs/lakehouse/__init__.py +2 -0
- sempy_labs/lakehouse/_lakehouse.py +6 -7
- sempy_labs/lakehouse/_shortcuts.py +198 -57
- sempy_labs/migration/_migration_validation.py +0 -4
- sempy_labs/report/_download_report.py +4 -6
- sempy_labs/report/_generate_report.py +15 -23
- sempy_labs/report/_report_bpa.py +12 -19
- sempy_labs/report/_report_functions.py +2 -1
- sempy_labs/report/_report_rebind.py +8 -6
- sempy_labs/tom/_model.py +34 -16
- {semantic_link_labs-0.9.4.dist-info → semantic_link_labs-0.9.6.dist-info}/LICENSE +0 -0
- {semantic_link_labs-0.9.4.dist-info → semantic_link_labs-0.9.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
from sempy_labs._helper_functions import (
|
|
2
|
+
_base_api,
|
|
3
|
+
_build_url,
|
|
4
|
+
_encode_user,
|
|
5
|
+
)
|
|
6
|
+
from uuid import UUID
|
|
7
|
+
from typing import Optional
|
|
8
|
+
from sempy_labs.admin._basic_functions import (
|
|
9
|
+
_resolve_workspace_name_and_id,
|
|
10
|
+
)
|
|
11
|
+
import sempy_labs._icons as icons
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def add_user_to_workspace(
|
|
15
|
+
user: str | UUID,
|
|
16
|
+
role: str = "Member",
|
|
17
|
+
principal_type: str = "User",
|
|
18
|
+
workspace: Optional[str | UUID] = None,
|
|
19
|
+
):
|
|
20
|
+
"""
|
|
21
|
+
Grants user permissions to the specified workspace.
|
|
22
|
+
|
|
23
|
+
This is a wrapper function for the following API: `Admin - Groups AddUserAsAdmin <https://learn.microsoft.com/rest/api/power-bi/admin/groups-add-user-as-admin>`_.
|
|
24
|
+
|
|
25
|
+
Parameters
|
|
26
|
+
----------
|
|
27
|
+
user : str | uuid.UUID
|
|
28
|
+
The user identifier or email address. For service principals and groups you must use the user identifier.
|
|
29
|
+
role : str, default="Member"
|
|
30
|
+
The role of the user in the workspace. Options are: 'Admin', 'Contributor', 'Member', 'None', 'Viewer'.
|
|
31
|
+
principal_type : str, default="User"
|
|
32
|
+
The principal type of the user. Options are: 'App', 'Group', 'None', 'User'.
|
|
33
|
+
workspace : str | uuid.UUID, default=None
|
|
34
|
+
The Fabric workspace name or ID.
|
|
35
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
36
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
(workspace_name, workspace_id) = _resolve_workspace_name_and_id(workspace)
|
|
40
|
+
|
|
41
|
+
# Validation
|
|
42
|
+
role = role.capitalize()
|
|
43
|
+
roles = ["Admin", "Contributor", "Member", "None", "Viewer"]
|
|
44
|
+
if role not in roles:
|
|
45
|
+
raise ValueError(f"{icons.red_dot} Invalid role. Please choose from {roles}")
|
|
46
|
+
principal_types = ["App", "Group", "None", "User"]
|
|
47
|
+
if principal_type not in principal_types:
|
|
48
|
+
raise ValueError(
|
|
49
|
+
f"{icons.red_dot} Invalid principal type. Please choose from {principal_types}"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
user = _encode_user(user)
|
|
53
|
+
|
|
54
|
+
payload = {
|
|
55
|
+
"identifier": user, # identifier or emailAddress?
|
|
56
|
+
"principalType": principal_type,
|
|
57
|
+
"groupUserAccessRight": role,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
_base_api(
|
|
61
|
+
request=f"/v1.0/myorg/admin/groups/{workspace_id}/users",
|
|
62
|
+
method="post",
|
|
63
|
+
payload=payload,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
print(
|
|
67
|
+
f"{icons.green_dot} The '{user}' user has been added with '{role.lower()}' permissions to the '{workspace_name}' workspace."
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def delete_user_from_workspace(
|
|
72
|
+
user: str | UUID,
|
|
73
|
+
workspace: Optional[str | UUID] = None,
|
|
74
|
+
is_group: Optional[bool] = None,
|
|
75
|
+
profile_id: Optional[str] = None,
|
|
76
|
+
):
|
|
77
|
+
"""
|
|
78
|
+
Removes user permissions from the specified workspace.
|
|
79
|
+
|
|
80
|
+
This is a wrapper function for the following API: `Admin - Groups DeleteUserAsAdmin <https://learn.microsoft.com/rest/api/power-bi/admin/groups-delete-user-as-admin>`_.
|
|
81
|
+
|
|
82
|
+
Parameters
|
|
83
|
+
----------
|
|
84
|
+
user : str | uuid.UUID
|
|
85
|
+
The user identifier or email address. For service principals and groups you must use the user identifier.
|
|
86
|
+
workspace : str | uuid.UUID, default=None
|
|
87
|
+
The Fabric workspace name or ID.
|
|
88
|
+
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
89
|
+
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
90
|
+
is_group : bool, default=None
|
|
91
|
+
Whether a given user is a group or not. This parameter is required when user to delete is group.
|
|
92
|
+
profile_id : str, default=None
|
|
93
|
+
The service principal profile ID to delete.
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
(workspace_name, workspace_id) = _resolve_workspace_name_and_id(workspace)
|
|
97
|
+
|
|
98
|
+
user = _encode_user(user)
|
|
99
|
+
url = f"/v1.0/myorg/admin/groups/{workspace_id}/users/{user}"
|
|
100
|
+
|
|
101
|
+
params = {}
|
|
102
|
+
if profile_id is not None:
|
|
103
|
+
params["profileId"] = profile_id
|
|
104
|
+
if is_group is not None:
|
|
105
|
+
params["isGroup"] = is_group
|
|
106
|
+
|
|
107
|
+
url = _build_url(url, params)
|
|
108
|
+
|
|
109
|
+
_base_api(
|
|
110
|
+
request=url,
|
|
111
|
+
method="delete",
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
print(
|
|
115
|
+
f"{icons.green_dot} The '{user}' user has been removed from the '{workspace_name}' workspace."
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def restore_deleted_workspace(workspace_id: UUID, name: str, email_address: str):
|
|
120
|
+
"""
|
|
121
|
+
Restores a deleted workspace.
|
|
122
|
+
|
|
123
|
+
This is a wrapper function for the following API: `Admin - Groups RestoreDeletedGroupAsAdmin <https://learn.microsoft.com/rest/api/power-bi/admin/groups-restore-deleted-group-as-admin>`_.
|
|
124
|
+
|
|
125
|
+
Parameters
|
|
126
|
+
----------
|
|
127
|
+
workspace_id : uuid.UUID
|
|
128
|
+
The ID of the workspace to restore.
|
|
129
|
+
name : str
|
|
130
|
+
The name of the group to be restored
|
|
131
|
+
email_address : str
|
|
132
|
+
The email address of the owner of the group to be restored
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
payload = {
|
|
136
|
+
"name": name,
|
|
137
|
+
"emailAddress": email_address,
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
_base_api(
|
|
141
|
+
request=f"/v1.0/myorg/admin/groups/{workspace_id}/restore",
|
|
142
|
+
method="post",
|
|
143
|
+
payload=payload,
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
print(
|
|
147
|
+
f"{icons.green_dot} The '{workspace_id}' workspace has been restored as '{name}'."
|
|
148
|
+
)
|
|
@@ -4,6 +4,7 @@ from sempy_labs._helper_functions import (
|
|
|
4
4
|
format_dax_object_name,
|
|
5
5
|
resolve_workspace_name_and_id,
|
|
6
6
|
resolve_dataset_name_and_id,
|
|
7
|
+
resolve_workspace_name,
|
|
7
8
|
)
|
|
8
9
|
from IPython.display import display
|
|
9
10
|
from sempy_labs.lakehouse import get_lakehouse_columns
|
|
@@ -70,7 +71,7 @@ def direct_lake_schema_compare(
|
|
|
70
71
|
f"{icons.red_dot} This function only supports Direct Lake semantic models where the source lakehouse resides in the same workpace as the semantic model."
|
|
71
72
|
)
|
|
72
73
|
|
|
73
|
-
lakehouse_workspace =
|
|
74
|
+
lakehouse_workspace = resolve_workspace_name(workspace_id=lakehouse_workspace_id)
|
|
74
75
|
dfT = fabric.list_tables(dataset=dataset_id, workspace=workspace_id)
|
|
75
76
|
dfC = fabric.list_columns(dataset=dataset_id, workspace=workspace_id)
|
|
76
77
|
lc = get_lakehouse_columns(lakehouse_name, lakehouse_workspace)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import sempy
|
|
2
|
-
import
|
|
2
|
+
import pandas as pd
|
|
3
3
|
from sempy_labs.lakehouse import get_lakehouse_columns
|
|
4
4
|
from sempy_labs.directlake._dl_helper import get_direct_lake_source
|
|
5
5
|
from sempy_labs.tom import connect_semantic_model
|
|
@@ -19,8 +19,8 @@ def direct_lake_schema_sync(
|
|
|
19
19
|
dataset: str | UUID,
|
|
20
20
|
workspace: Optional[str | UUID] = None,
|
|
21
21
|
add_to_model: bool = False,
|
|
22
|
-
|
|
23
|
-
):
|
|
22
|
+
remove_from_model: bool = False,
|
|
23
|
+
) -> pd.DataFrame:
|
|
24
24
|
"""
|
|
25
25
|
Shows/adds columns which exist in the lakehouse but do not exist in the semantic model (only for tables in the semantic model).
|
|
26
26
|
|
|
@@ -34,22 +34,18 @@ def direct_lake_schema_sync(
|
|
|
34
34
|
or if no lakehouse attached, resolves to the workspace of the notebook.
|
|
35
35
|
add_to_model : bool, default=False
|
|
36
36
|
If set to True, columns which exist in the lakehouse but do not exist in the semantic model are added to the semantic model. No new tables are added.
|
|
37
|
+
remove_from_model : bool, default=False
|
|
38
|
+
If set to True, columns which exist in the semantic model but do not exist in the lakehouse are removed from the semantic model. No new tables are removed.
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
pandas.DataFrame
|
|
43
|
+
A pandas dataframe showing the status of columns in the semantic model and lakehouse (prior to adding/removing them from the model using this function).
|
|
37
44
|
"""
|
|
38
45
|
|
|
39
46
|
sempy.fabric._client._utils._init_analysis_services()
|
|
40
47
|
import Microsoft.AnalysisServices.Tabular as TOM
|
|
41
48
|
|
|
42
|
-
if "lakehouse" in kwargs:
|
|
43
|
-
print(
|
|
44
|
-
"The 'lakehouse' parameter has been deprecated as it is no longer necessary. Please remove this parameter from the function going forward."
|
|
45
|
-
)
|
|
46
|
-
del kwargs["lakehouse"]
|
|
47
|
-
if "lakehouse_workspace" in kwargs:
|
|
48
|
-
print(
|
|
49
|
-
"The 'lakehouse_workspace' parameter has been deprecated as it is no longer necessary. Please remove this parameter from the function going forward."
|
|
50
|
-
)
|
|
51
|
-
del kwargs["lakehouse_workspace"]
|
|
52
|
-
|
|
53
49
|
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
54
50
|
(dataset_name, dataset_id) = resolve_dataset_name_and_id(dataset, workspace_id)
|
|
55
51
|
|
|
@@ -67,14 +63,54 @@ def direct_lake_schema_sync(
|
|
|
67
63
|
f"{icons.red_dot} This function only supports Direct Lake semantic models where the source lakehouse resides in the same workpace as the semantic model."
|
|
68
64
|
)
|
|
69
65
|
|
|
70
|
-
|
|
66
|
+
lc = get_lakehouse_columns(lakehouse_id, lakehouse_workspace_id)
|
|
71
67
|
|
|
72
|
-
|
|
68
|
+
readonly = True
|
|
69
|
+
if add_to_model or remove_from_model:
|
|
70
|
+
readonly = False
|
|
71
|
+
df = pd.DataFrame(
|
|
72
|
+
columns=[
|
|
73
|
+
"TableName",
|
|
74
|
+
"ColumnName",
|
|
75
|
+
"SourceTableName",
|
|
76
|
+
"SourceColumnName",
|
|
77
|
+
"Status",
|
|
78
|
+
]
|
|
79
|
+
)
|
|
73
80
|
|
|
74
81
|
with connect_semantic_model(
|
|
75
|
-
dataset=dataset_id, readonly=
|
|
82
|
+
dataset=dataset_id, readonly=readonly, workspace=workspace_id
|
|
76
83
|
) as tom:
|
|
84
|
+
# Check if the columns in the semantic model exist in the lakehouse
|
|
85
|
+
for c in tom.all_columns():
|
|
86
|
+
partition_name = next(p.Name for p in c.Table.Partitions)
|
|
87
|
+
p = c.Table.Partitions[partition_name]
|
|
88
|
+
if p.SourceType == TOM.PartitionSourceType.Entity:
|
|
89
|
+
entity_name = p.Source.EntityName
|
|
90
|
+
source_column = c.SourceColumn
|
|
91
|
+
lc_filt = lc[
|
|
92
|
+
(lc["Table Name"] == entity_name)
|
|
93
|
+
& (lc["Column Name"] == source_column)
|
|
94
|
+
]
|
|
95
|
+
# Remove column from model if it doesn't exist in the lakehouse
|
|
96
|
+
if lc_filt.empty:
|
|
97
|
+
new_data = {
|
|
98
|
+
"TableName": c.Parent.Name,
|
|
99
|
+
"ColumnName": c.Name,
|
|
100
|
+
"SourceTableName": entity_name,
|
|
101
|
+
"SourceColumnName": source_column,
|
|
102
|
+
"Status": "Not in lakehouse",
|
|
103
|
+
}
|
|
104
|
+
df = pd.concat(
|
|
105
|
+
[df, pd.DataFrame(new_data, index=[0])], ignore_index=True
|
|
106
|
+
)
|
|
107
|
+
if remove_from_model:
|
|
108
|
+
tom.remove_object(object=c)
|
|
109
|
+
print(
|
|
110
|
+
f"{icons.green_dot} The '{c.Parent.Name}'[{c.Name}] column has been removed from the '{dataset_name}' semantic model within the '{workspace_name}' workspace."
|
|
111
|
+
)
|
|
77
112
|
|
|
113
|
+
# Check if the lakehouse columns exist in the semantic model
|
|
78
114
|
for i, r in lc.iterrows():
|
|
79
115
|
lakeTName = r["Table Name"]
|
|
80
116
|
lakeCName = r["Column Name"]
|
|
@@ -97,9 +133,17 @@ def direct_lake_schema_sync(
|
|
|
97
133
|
c.SourceColumn == lakeCName and c.Parent.Name == table_name
|
|
98
134
|
for c in tom.all_columns()
|
|
99
135
|
):
|
|
100
|
-
|
|
101
|
-
|
|
136
|
+
new_data = {
|
|
137
|
+
"TableName": table_name,
|
|
138
|
+
"ColumnName": None,
|
|
139
|
+
"SourceTableName": lakeTName,
|
|
140
|
+
"SourceColumnName": lakeCName,
|
|
141
|
+
"Status": "Not in semantic model",
|
|
142
|
+
}
|
|
143
|
+
df = pd.concat(
|
|
144
|
+
[df, pd.DataFrame(new_data, index=[0])], ignore_index=True
|
|
102
145
|
)
|
|
146
|
+
|
|
103
147
|
if add_to_model:
|
|
104
148
|
dt = _convert_data_type(dType)
|
|
105
149
|
tom.add_data_column(
|
|
@@ -111,3 +155,5 @@ def direct_lake_schema_sync(
|
|
|
111
155
|
print(
|
|
112
156
|
f"{icons.green_dot} The '{lakeCName}' column in the '{lakeTName}' lakehouse table was added to the '{dataset_name}' semantic model within the '{workspace_name}' workspace."
|
|
113
157
|
)
|
|
158
|
+
|
|
159
|
+
return df
|
|
@@ -7,7 +7,6 @@ import sempy_labs._icons as icons
|
|
|
7
7
|
from sempy._utils._log import log
|
|
8
8
|
from sempy_labs._helper_functions import (
|
|
9
9
|
retry,
|
|
10
|
-
resolve_lakehouse_name,
|
|
11
10
|
_convert_data_type,
|
|
12
11
|
resolve_dataset_name_and_id,
|
|
13
12
|
resolve_workspace_name_and_id,
|
|
@@ -129,11 +128,6 @@ def generate_direct_lake_semantic_model(
|
|
|
129
128
|
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
130
129
|
if lakehouse_workspace is None:
|
|
131
130
|
lakehouse_workspace = workspace
|
|
132
|
-
if lakehouse is None:
|
|
133
|
-
lakehouse_id = fabric.get_lakehouse_id()
|
|
134
|
-
lakehouse_workspace_id = fabric.get_workspace_id()
|
|
135
|
-
lakehouse_workspace = fabric.resolve_workspace_name(lakehouse_workspace_id)
|
|
136
|
-
lakehouse = resolve_lakehouse_name(lakehouse_id, lakehouse_workspace)
|
|
137
131
|
|
|
138
132
|
dfLT = get_lakehouse_tables(lakehouse=lakehouse, workspace=lakehouse_workspace)
|
|
139
133
|
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import sempy.fabric as fabric
|
|
2
1
|
from sempy_labs._helper_functions import (
|
|
3
|
-
resolve_lakehouse_name,
|
|
4
|
-
resolve_lakehouse_id,
|
|
5
|
-
resolve_warehouse_id,
|
|
6
2
|
resolve_workspace_name_and_id,
|
|
7
3
|
_base_api,
|
|
4
|
+
resolve_lakehouse_name_and_id,
|
|
5
|
+
resolve_item_name_and_id,
|
|
8
6
|
)
|
|
9
7
|
from typing import Optional
|
|
10
8
|
import sempy_labs._icons as icons
|
|
@@ -45,13 +43,14 @@ def generate_shared_expression(
|
|
|
45
43
|
f"{icons.red_dot} Invalid item type. Valid options: {item_types}."
|
|
46
44
|
)
|
|
47
45
|
|
|
48
|
-
if
|
|
49
|
-
item_id =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
if item_type == "Lakehouse":
|
|
47
|
+
(item_name, item_id) = resolve_lakehouse_name_and_id(
|
|
48
|
+
lakehouse=item_name, workspace=workspace_id
|
|
49
|
+
)
|
|
50
|
+
else:
|
|
51
|
+
(item_name, item_id) = resolve_item_name_and_id(
|
|
52
|
+
item=item_name, type=item_type, workspace=workspace_id
|
|
53
|
+
)
|
|
55
54
|
|
|
56
55
|
item_type_rest = f"{item_type.lower()}s"
|
|
57
56
|
response = _base_api(
|
|
@@ -48,6 +48,7 @@ def get_sku_size(workspace: Optional[str | UUID] = None) -> str:
|
|
|
48
48
|
str
|
|
49
49
|
The SKU size for a workspace.
|
|
50
50
|
"""
|
|
51
|
+
from sempy_labs._capacities import list_capacities
|
|
51
52
|
|
|
52
53
|
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
53
54
|
|
|
@@ -59,7 +60,7 @@ def get_sku_size(workspace: Optional[str | UUID] = None) -> str:
|
|
|
59
60
|
)
|
|
60
61
|
|
|
61
62
|
capacity_id = dfW["Capacity Id"].iloc[0]
|
|
62
|
-
dfC =
|
|
63
|
+
dfC = list_capacities()
|
|
63
64
|
dfC_filt = dfC[dfC["Id"] == capacity_id]
|
|
64
65
|
|
|
65
66
|
if len(dfC_filt) == 0:
|
|
@@ -4,6 +4,8 @@ from sempy_labs._helper_functions import (
|
|
|
4
4
|
resolve_lakehouse_name,
|
|
5
5
|
resolve_dataset_name_and_id,
|
|
6
6
|
resolve_workspace_name_and_id,
|
|
7
|
+
resolve_item_name_and_id,
|
|
8
|
+
resolve_lakehouse_name_and_id,
|
|
7
9
|
)
|
|
8
10
|
from sempy_labs.tom import connect_semantic_model
|
|
9
11
|
from typing import Optional
|
|
@@ -40,22 +42,9 @@ def update_direct_lake_model_lakehouse_connection(
|
|
|
40
42
|
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
|
|
41
43
|
(dataset_name, dataset_id) = resolve_dataset_name_and_id(dataset, workspace_id)
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if lakehouse is None:
|
|
47
|
-
lakehouse_id = fabric.get_lakehouse_id()
|
|
48
|
-
lakehouse = resolve_lakehouse_name(lakehouse_id, lakehouse_workspace)
|
|
49
|
-
|
|
50
|
-
# Check if lakehouse is valid
|
|
51
|
-
dfI = fabric.list_items(workspace=lakehouse_workspace, type="Lakehouse")
|
|
52
|
-
dfI_filt = dfI[(dfI["Display Name"] == lakehouse)]
|
|
53
|
-
|
|
54
|
-
if len(dfI_filt) == 0:
|
|
55
|
-
raise ValueError(
|
|
56
|
-
f"{icons.red_dot} The '{lakehouse}' lakehouse does not exist within the '{lakehouse_workspace}' workspace. "
|
|
57
|
-
f"Therefore it cannot be used to support the '{dataset_name}' semantic model within the '{workspace_name}' workspace."
|
|
58
|
-
)
|
|
45
|
+
(lakehouse_name, lakehouse_id) = resolve_lakehouse_name_and_id(
|
|
46
|
+
lakehouse=lakehouse, workspace=lakehouse_workspace
|
|
47
|
+
)
|
|
59
48
|
|
|
60
49
|
icons.sll_tags.append("UpdateDLConnection")
|
|
61
50
|
|
|
@@ -121,21 +110,19 @@ def update_direct_lake_model_connection(
|
|
|
121
110
|
if source_workspace is None:
|
|
122
111
|
source_workspace = workspace_name
|
|
123
112
|
|
|
124
|
-
if
|
|
125
|
-
source_id =
|
|
126
|
-
|
|
127
|
-
else:
|
|
128
|
-
source_id = fabric.resolve_item_id(
|
|
129
|
-
item_name=source, type=source_type, workspace=source_workspace
|
|
113
|
+
if source_type == "Lakehouse":
|
|
114
|
+
(source_name, source_id) = resolve_lakehouse_name_and_id(
|
|
115
|
+
lakehouse=source, workspace=source_workspace
|
|
130
116
|
)
|
|
131
|
-
|
|
132
|
-
|
|
117
|
+
else:
|
|
118
|
+
(source_name, source_id) = resolve_item_name_and_id(
|
|
119
|
+
item=source, type=source_type, workspace=source_workspace
|
|
133
120
|
)
|
|
134
121
|
|
|
135
122
|
icons.sll_tags.append("UpdateDLConnection")
|
|
136
123
|
|
|
137
124
|
shEx = generate_shared_expression(
|
|
138
|
-
item_name=
|
|
125
|
+
item_name=source_name, item_type=source_type, workspace=source_workspace
|
|
139
126
|
)
|
|
140
127
|
|
|
141
128
|
with connect_semantic_model(
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import sempy
|
|
2
|
-
import sempy.fabric as fabric
|
|
3
2
|
from sempy_labs.tom import connect_semantic_model
|
|
4
3
|
from sempy_labs._refresh_semantic_model import refresh_semantic_model
|
|
5
4
|
from sempy_labs.directlake._dl_helper import get_direct_lake_source
|
|
@@ -7,6 +6,7 @@ from sempy_labs._helper_functions import (
|
|
|
7
6
|
_convert_data_type,
|
|
8
7
|
resolve_dataset_name_and_id,
|
|
9
8
|
resolve_workspace_name_and_id,
|
|
9
|
+
resolve_workspace_name,
|
|
10
10
|
)
|
|
11
11
|
from typing import List, Optional, Union
|
|
12
12
|
import sempy_labs._icons as icons
|
|
@@ -17,6 +17,7 @@ def update_direct_lake_partition_entity(
|
|
|
17
17
|
dataset: str | UUID,
|
|
18
18
|
table_name: Union[str, List[str]],
|
|
19
19
|
entity_name: Union[str, List[str]],
|
|
20
|
+
schema: Optional[str] = None,
|
|
20
21
|
workspace: Optional[str | UUID] = None,
|
|
21
22
|
):
|
|
22
23
|
"""
|
|
@@ -30,6 +31,9 @@ def update_direct_lake_partition_entity(
|
|
|
30
31
|
Name of the table(s) in the semantic model.
|
|
31
32
|
entity_name : str, List[str]
|
|
32
33
|
Name of the lakehouse table to be mapped to the semantic model table.
|
|
34
|
+
schema : str, default=None
|
|
35
|
+
The schema of the lakehouse table to be mapped to the semantic model table.
|
|
36
|
+
Defaults to None which resolves to the existing schema of the lakehouse table.
|
|
33
37
|
workspace : str | uuid.UUID, default=None
|
|
34
38
|
The Fabric workspace name or ID in which the semantic model exists.
|
|
35
39
|
Defaults to None which resolves to the workspace of the attached lakehouse
|
|
@@ -79,9 +83,13 @@ def update_direct_lake_partition_entity(
|
|
|
79
83
|
tom.model.Tables[tName].Partitions[part_name].Source.EntityName = eName
|
|
80
84
|
|
|
81
85
|
# Update source lineage tag
|
|
82
|
-
|
|
86
|
+
existing_schema = (
|
|
83
87
|
tom.model.Tables[tName].Partitions[part_name].Source.SchemaName or "dbo"
|
|
84
88
|
)
|
|
89
|
+
if schema is None:
|
|
90
|
+
schema = existing_schema
|
|
91
|
+
|
|
92
|
+
tom.model.Tables[tName].Partitions[part_name].Source.SchemaName = schema
|
|
85
93
|
tom.model.Tables[tName].SourceLineageTag = f"[{schema}].[{eName}]"
|
|
86
94
|
print(
|
|
87
95
|
f"{icons.green_dot} The '{tName}' table in the '{dataset_name}' semantic model within the '{workspace_name}' workspace has been updated to point to the '{eName}' table."
|
|
@@ -136,7 +144,7 @@ def add_table_to_direct_lake_semantic_model(
|
|
|
136
144
|
f"{icons.red_dot} This function only supports Direct Lake semantic models where the source lakehouse resides in the same workpace as the semantic model."
|
|
137
145
|
)
|
|
138
146
|
|
|
139
|
-
lakehouse_workspace =
|
|
147
|
+
lakehouse_workspace = resolve_workspace_name(workspace_id=lakehouse_workspace_id)
|
|
140
148
|
|
|
141
149
|
with connect_semantic_model(
|
|
142
150
|
dataset=dataset_id, readonly=False, workspace=workspace_id
|
sempy_labs/lakehouse/__init__.py
CHANGED
|
@@ -12,6 +12,7 @@ from sempy_labs.lakehouse._shortcuts import (
|
|
|
12
12
|
create_shortcut_onelake,
|
|
13
13
|
delete_shortcut,
|
|
14
14
|
reset_shortcut_cache,
|
|
15
|
+
list_shortcuts,
|
|
15
16
|
)
|
|
16
17
|
|
|
17
18
|
__all__ = [
|
|
@@ -25,4 +26,5 @@ __all__ = [
|
|
|
25
26
|
"vacuum_lakehouse_tables",
|
|
26
27
|
"reset_shortcut_cache",
|
|
27
28
|
"run_table_maintenance",
|
|
29
|
+
"list_shortcuts",
|
|
28
30
|
]
|
|
@@ -35,7 +35,7 @@ def lakehouse_attached() -> bool:
|
|
|
35
35
|
@log
|
|
36
36
|
def optimize_lakehouse_tables(
|
|
37
37
|
tables: Optional[Union[str, List[str]]] = None,
|
|
38
|
-
lakehouse: Optional[str] = None,
|
|
38
|
+
lakehouse: Optional[str | UUID] = None,
|
|
39
39
|
workspace: Optional[str | UUID] = None,
|
|
40
40
|
):
|
|
41
41
|
"""
|
|
@@ -46,8 +46,8 @@ def optimize_lakehouse_tables(
|
|
|
46
46
|
tables : str | List[str], default=None
|
|
47
47
|
The table(s) to optimize.
|
|
48
48
|
Defaults to None which resovles to optimizing all tables within the lakehouse.
|
|
49
|
-
lakehouse : str, default=None
|
|
50
|
-
The Fabric lakehouse.
|
|
49
|
+
lakehouse : str | uuid.UUID, default=None
|
|
50
|
+
The Fabric lakehouse name or ID.
|
|
51
51
|
Defaults to None which resolves to the lakehouse attached to the notebook.
|
|
52
52
|
workspace : str | uuid.UUID, default=None
|
|
53
53
|
The Fabric workspace name or ID used by the lakehouse.
|
|
@@ -82,7 +82,7 @@ def optimize_lakehouse_tables(
|
|
|
82
82
|
@log
|
|
83
83
|
def vacuum_lakehouse_tables(
|
|
84
84
|
tables: Optional[Union[str, List[str]]] = None,
|
|
85
|
-
lakehouse: Optional[str] = None,
|
|
85
|
+
lakehouse: Optional[str | UUID] = None,
|
|
86
86
|
workspace: Optional[str | UUID] = None,
|
|
87
87
|
retain_n_hours: Optional[int] = None,
|
|
88
88
|
):
|
|
@@ -93,8 +93,8 @@ def vacuum_lakehouse_tables(
|
|
|
93
93
|
----------
|
|
94
94
|
tables : str | List[str] | None
|
|
95
95
|
The table(s) to vacuum. If no tables are specified, all tables in the lakehouse will be optimized.
|
|
96
|
-
lakehouse : str, default=None
|
|
97
|
-
The Fabric lakehouse.
|
|
96
|
+
lakehouse : str | uuid.UUID, default=None
|
|
97
|
+
The Fabric lakehouse name or ID.
|
|
98
98
|
Defaults to None which resolves to the lakehouse attached to the notebook.
|
|
99
99
|
workspace : str | uuid.UUID, default=None
|
|
100
100
|
The Fabric workspace name or ID used by the lakehouse.
|
|
@@ -107,7 +107,6 @@ def vacuum_lakehouse_tables(
|
|
|
107
107
|
The default retention period is 168 hours (7 days) unless manually configured via table properties.
|
|
108
108
|
"""
|
|
109
109
|
|
|
110
|
-
from pyspark.sql import SparkSession
|
|
111
110
|
from sempy_labs.lakehouse._get_lakehouse_tables import get_lakehouse_tables
|
|
112
111
|
from delta import DeltaTable
|
|
113
112
|
|