From 43c6c5080f0d43172cca57050ce6fba2dedcbccf Mon Sep 17 00:00:00 2001 From: Alexander Korn Date: Tue, 5 May 2026 14:38:35 +0200 Subject: [PATCH 1/3] Add fix_isavailable_in_mdx_true: set IsAvailableInMDX=True on visible attribute columns --- .../_Fix_IsAvailableInMdxTrue.py | 57 +++++++++++++++++++ src/sempy_labs/semantic_model/__init__.py | 3 + 2 files changed, 60 insertions(+) create mode 100644 src/sempy_labs/semantic_model/_Fix_IsAvailableInMdxTrue.py diff --git a/src/sempy_labs/semantic_model/_Fix_IsAvailableInMdxTrue.py b/src/sempy_labs/semantic_model/_Fix_IsAvailableInMdxTrue.py new file mode 100644 index 000000000..8a42fcac4 --- /dev/null +++ b/src/sempy_labs/semantic_model/_Fix_IsAvailableInMdxTrue.py @@ -0,0 +1,57 @@ +# Fix "Set IsAvailableInMdx to true on necessary columns" — standalone BPA fixer. + +from typing import Optional +from uuid import UUID + + +def fix_isavailable_in_mdx_true( + dataset: str, + workspace: Optional[str | UUID] = None, + scan_only: bool = False, +): + """ + Sets IsAvailableInMDX to True on key/attribute columns that incorrectly have it False. + + Targets columns that are: (a) used as keys in relationships (To side), or + (b) used in hierarchies, or (c) marked as IsKey. + + Parameters + ---------- + dataset : str + Name of the semantic model. + workspace : str | uuid.UUID, default=None + The Fabric workspace name or ID. + scan_only : bool, default=False + If True, only reports what would be fixed without making changes. + """ + from sempy_labs.tom import connect_semantic_model + + fixed = 0 + with connect_semantic_model(dataset=dataset, readonly=scan_only, workspace=workspace) as tom: + # Collect columns that should have IsAvailableInMDX = True + needed = set() + for rel in tom.model.Relationships: + needed.add((str(rel.ToTable.Name), str(rel.ToColumn.Name))) + for table in tom.model.Tables: + for h in table.Hierarchies: + for lvl in h.Levels: + needed.add((str(table.Name), str(lvl.Column.Name))) + for col in table.Columns: + if col.IsKey: + needed.add((str(table.Name), str(col.Name))) + + for table in tom.model.Tables: + for col in table.Columns: + if (table.Name, col.Name) in needed and not col.IsAvailableInMDX: + if scan_only: + print(f" Would fix: '{table.Name}'[{col.Name}] IsAvailableInMDX → True") + else: + col.IsAvailableInMDX = True + print(f" Fixed: '{table.Name}'[{col.Name}] IsAvailableInMDX → True") + fixed += 1 + if not scan_only and fixed > 0: + tom.model.SaveChanges() + + action = "Would fix" if scan_only else "Fixed" + print(f" {action} {fixed} column(s).") + return fixed diff --git a/src/sempy_labs/semantic_model/__init__.py b/src/sempy_labs/semantic_model/__init__.py index 7c117f392..58137fadb 100644 --- a/src/sempy_labs/semantic_model/__init__.py +++ b/src/sempy_labs/semantic_model/__init__.py @@ -13,3 +13,6 @@ "make_discoverable", "enable_query_caching", ] + +from ._Fix_IsAvailableInMdxTrue import fix_isavailable_in_mdx_true +__all__ += ["fix_isavailable_in_mdx_true"] From dafe9266db784d36b68fb07f3a4ff6366bde8f81 Mon Sep 17 00:00:00 2001 From: Alexander Korn Date: Tue, 5 May 2026 15:02:39 +0200 Subject: [PATCH 2/3] Address Copilot review: mechanical fixes (drop SaveChanges, add @log, lint, init imports) --- src/sempy_labs/semantic_model/_Fix_IsAvailableInMdxTrue.py | 4 ++-- src/sempy_labs/semantic_model/__init__.py | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/sempy_labs/semantic_model/_Fix_IsAvailableInMdxTrue.py b/src/sempy_labs/semantic_model/_Fix_IsAvailableInMdxTrue.py index 8a42fcac4..1a1a76397 100644 --- a/src/sempy_labs/semantic_model/_Fix_IsAvailableInMdxTrue.py +++ b/src/sempy_labs/semantic_model/_Fix_IsAvailableInMdxTrue.py @@ -2,8 +2,10 @@ from typing import Optional from uuid import UUID +from sempy._utils._log import log +@log def fix_isavailable_in_mdx_true( dataset: str, workspace: Optional[str | UUID] = None, @@ -49,8 +51,6 @@ def fix_isavailable_in_mdx_true( col.IsAvailableInMDX = True print(f" Fixed: '{table.Name}'[{col.Name}] IsAvailableInMDX → True") fixed += 1 - if not scan_only and fixed > 0: - tom.model.SaveChanges() action = "Would fix" if scan_only else "Fixed" print(f" {action} {fixed} column(s).") diff --git a/src/sempy_labs/semantic_model/__init__.py b/src/sempy_labs/semantic_model/__init__.py index 58137fadb..1b2fe5ede 100644 --- a/src/sempy_labs/semantic_model/__init__.py +++ b/src/sempy_labs/semantic_model/__init__.py @@ -6,13 +6,12 @@ from ._caching import ( enable_query_caching, ) +from ._Fix_IsAvailableInMdxTrue import fix_isavailable_in_mdx_true __all__ = [ "approved_for_copilot", "set_endorsement", "make_discoverable", "enable_query_caching", + "fix_isavailable_in_mdx_true", ] - -from ._Fix_IsAvailableInMdxTrue import fix_isavailable_in_mdx_true -__all__ += ["fix_isavailable_in_mdx_true"] From 529610f6cef26646839f4ce91f0b1c644571be4b Mon Sep 17 00:00:00 2001 From: Alexander Korn Date: Tue, 5 May 2026 15:29:56 +0200 Subject: [PATCH 3/3] Address Copilot review (wave 2): API/docs/safety fixes --- .../semantic_model/_Fix_IsAvailableInMdxTrue.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/sempy_labs/semantic_model/_Fix_IsAvailableInMdxTrue.py b/src/sempy_labs/semantic_model/_Fix_IsAvailableInMdxTrue.py index 1a1a76397..179718dbb 100644 --- a/src/sempy_labs/semantic_model/_Fix_IsAvailableInMdxTrue.py +++ b/src/sempy_labs/semantic_model/_Fix_IsAvailableInMdxTrue.py @@ -7,10 +7,10 @@ @log def fix_isavailable_in_mdx_true( - dataset: str, + dataset: str | UUID, workspace: Optional[str | UUID] = None, scan_only: bool = False, -): +) -> int: """ Sets IsAvailableInMDX to True on key/attribute columns that incorrectly have it False. @@ -19,12 +19,17 @@ def fix_isavailable_in_mdx_true( Parameters ---------- - dataset : str - Name of the semantic model. + dataset : str | UUID + Name or ID of the semantic model. workspace : str | uuid.UUID, default=None The Fabric workspace name or ID. scan_only : bool, default=False If True, only reports what would be fixed without making changes. + + Returns + ------- + int + Number of items fixed. """ from sempy_labs.tom import connect_semantic_model