Skip to content

Commit f9e914c

Browse files
committed
Merge branch 'm-kovalsky/issue659'
2 parents 3fd47fd + 162f542 commit f9e914c

File tree

2 files changed

+60
-6
lines changed

2 files changed

+60
-6
lines changed

src/sempy_labs/directlake/_generate_shared_expression.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
_base_api,
44
resolve_lakehouse_name_and_id,
55
resolve_item_name_and_id,
6+
_get_fabric_context_setting,
67
)
78
from typing import Optional
89
import sempy_labs._icons as icons
@@ -85,4 +86,7 @@ def generate_shared_expression(
8586
return f"{start_expr}{mid_expr}{end_expr}"
8687
else:
8788
# Build DL/OL expression
88-
return f"""let\n\tSource = AzureStorage.DataLake("onelake.dfs.fabric.microsoft.com/{workspace_id}/{item_id}")\nin\n\tSource"""
89+
env = _get_fabric_context_setting("spark.trident.pbienv").lower()
90+
env = "" if env == "prod" else f"{env}-"
91+
92+
return f"""let\n\tSource = AzureStorage.DataLake("https://{env}onelake.dfs.fabric.microsoft.com/{workspace_id}/{item_id}")\nin\n\tSource"""

src/sempy_labs/directlake/_update_directlake_model_lakehouse_connection.py

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
)
88
from sempy._utils._log import log
99
from sempy_labs.tom import connect_semantic_model
10-
from typing import Optional
10+
from typing import Optional, List
1111
import sempy_labs._icons as icons
1212
from uuid import UUID
1313
import re
@@ -19,7 +19,9 @@ def _extract_expression_list(expression):
1919
"""
2020

2121
pattern_sql = r'Sql\.Database\s*\(\s*"([^"]+)"\s*,\s*"([^"]+)"\s*\)'
22-
pattern_no_sql = r'AzureDataLakeStorage\s*\{\s*"server".*?:\s*onelake\.dfs\.fabric\.microsoft\.com"\s*,\s*"path"\s*:\s*"/([\da-fA-F-]+)\s*/\s*([\da-fA-F-]+)\s*/"\s*\}'
22+
pattern_no_sql = (
23+
r'AzureStorage\.DataLake\(".*?/([0-9a-fA-F\-]{36})/([0-9a-fA-F\-]{36})"'
24+
)
2325

2426
match_sql = re.search(pattern_sql, expression)
2527
match_no_sql = re.search(pattern_no_sql, expression)
@@ -102,6 +104,7 @@ def update_direct_lake_model_connection(
102104
source_type: str = "Lakehouse",
103105
source_workspace: Optional[str | UUID] = None,
104106
use_sql_endpoint: bool = True,
107+
tables: Optional[str | List[str]] = None,
105108
):
106109
"""
107110
Remaps a Direct Lake semantic model's SQL Endpoint connection to a new lakehouse/warehouse.
@@ -126,12 +129,19 @@ def update_direct_lake_model_connection(
126129
use_sql_endpoint : bool, default=True
127130
If True, the SQL Endpoint will be used for the connection.
128131
If False, Direct Lake over OneLake will be used.
132+
tables : str | List[str], default=None
133+
The name(s) of the table(s) to update in the Direct Lake semantic model.
134+
If None, all tables will be updated (if there is only one expression).
135+
If multiple tables are specified, they must be provided as a list.
129136
"""
130137
if use_sql_endpoint:
131138
icons.sll_tags.append("UpdateDLConnection_SQL")
132139
else:
133140
icons.sll_tags.append("UpdateDLConnection_DLOL")
134141

142+
if isinstance(tables, str):
143+
tables = [tables]
144+
135145
(workspace_name, workspace_id) = resolve_workspace_name_and_id(workspace)
136146
(dataset_name, dataset_id) = resolve_dataset_name_and_id(dataset, workspace_id)
137147

@@ -174,14 +184,54 @@ def update_direct_lake_model_connection(
174184
)
175185

176186
# Update the single connection expression
177-
if len(expressions) == 1:
187+
if len(expressions) > 1 and not tables:
188+
print(
189+
f"{icons.info} Multiple expressions found in the model. Please specify the tables to update using the 'tables parameter."
190+
)
191+
return
192+
elif len(expressions) == 1 and not tables:
178193
expr = expressions[0]
179194
tom.model.Expressions[expr].Expression = shared_expression
180195

181196
print(
182197
f"{icons.green_dot} The expression in the '{dataset_name}' semantic model within the '{workspace_name}' workspace has been updated to point to the '{source}' {source_type.lower()} in the '{source_workspace}' workspace."
183198
)
184199
else:
185-
print(
186-
f"{icons.info} Multiple expressions found in the model. Please use the update_direct_lake_partition_entity function to update specific tables."
200+
import sempy
201+
202+
sempy.fabric._client._utils._init_analysis_services()
203+
import Microsoft.AnalysisServices.Tabular as TOM
204+
205+
expr_list = _extract_expression_list(shared_expression)
206+
207+
expr_name = next(
208+
(name for name, exp in expression_dict.items() if exp == expr_list),
209+
None,
187210
)
211+
212+
# If the expression does not already exist, create it
213+
def generate_unique_name(existing_names):
214+
i = 1
215+
while True:
216+
candidate = f"DatabaseQuery{i}"
217+
if candidate not in existing_names:
218+
return candidate
219+
i += 1
220+
221+
if not expr_name:
222+
expr_name = generate_unique_name(expressions)
223+
tom.add_expression(name=expr_name, expression=shared_expression)
224+
225+
all_tables = [t.Name for t in tom.model.Tables]
226+
for t_name in tables:
227+
if t_name not in all_tables:
228+
raise ValueError(
229+
f"{icons.red_dot} The table '{t_name}' does not exist in the '{dataset_name}' semantic model within the '{workspace_name}' workspace."
230+
)
231+
p = next(p for p in tom.model.Tables[t_name].Partitions)
232+
if p.Mode != TOM.ModeType.DirectLake:
233+
raise ValueError(
234+
f"{icons.red_dot} The table '{t_name}' in the '{dataset_name}' semantic model within the '{workspace_name}' workspace is not in Direct Lake mode. This function is only applicable to Direct Lake tables."
235+
)
236+
237+
p.Source.ExpressionSource = tom.model.Expressions[expr_name]

0 commit comments

Comments
 (0)