从语义模型读取数据并使用 python 编写 Power BI 可使用的数据

本文介绍如何使用 Microsoft Fabric 中的 SemPy Python 库读取数据和元数据,并评估语义模型中的度量值。 你还将了解如何写入可供语义模型使用的数据。

先决条件

  • 访问 Microsoft Fabric 中的数据科学体验。
  • 创建新的笔记本,将代码复制/粘贴到单元中
  • 对于 Spark 3.4 及以上版本,使用 Fabric 时,语义链接在默认运行时中可用,无需安装它。 如果使用的是 Spark 3.3 或更低版本,或者想要更新到最新版本的语义链接,则可以运行以下命令: python %pip install -U semantic-link  
  • 将湖屋添加到笔记本
  • 从 fabric-samples 存储库的数据集文件夹中下载“Customer Profitability Sample.pbix”语义模型,并将该语义模型保存在本地

将语义模型上传到工作区

本文中将使用“Customer Profitability Sample.pbix”语义模型。 此语义模型引用了一家制造营销材料的公司。 它包含各个业务部门的产品、客户和相应的收入数据。

  1. 在 Fabric 数据科学中打开你的工作区
  2. 选择“上传”>“浏览”,然后选择“Customer Profitability Sample.pbix”语义模型。

屏幕截图显示用于将语义模型上传到工作区的界面。

上传完成后,工作区将有三个新工件:Power BI 报表、仪表板和名为“Customer Profitability Sample”的语义模型。 本文中的步骤是基于该语义模型。

屏幕截图显示上传到工作区的 Power BI 文件中的项。

使用 Python 读取语义模型中的数据

SemPy Python API 可以从位于 Microsoft Fabric 工作区的语义模型中检索数据和元数据。 该 API 还可以对其执行查询。

笔记本、Power BI 数据集语义模型和湖屋可以位于同一工作区或不同工作区。 默认情况下,SemPy 尝试从以下工作区访问语义模型:

  • 如果已将湖屋附加到笔记本,则为湖屋的工作区。
  • 笔记本的工作区(如果没有附加湖屋)。

如果语义模型不在这两个工作区中,则在调用 SemPy 方法时必须指定语义模型的工作区。

从语义模型读取数据:

  1. 列出工作区中的可用语义模型。

    import sempy.fabric as fabric
    
    df_datasets = fabric.list_datasets()
    df_datasets
    
  2. 列出“Customer Profitability Sample”语义模型中可用的表

    df_tables = fabric.list_tables("Customer Profitability Sample", include_columns=True)
    df_tables
    
  3. 列出“Customer Profitability Sample”语义模型中定义的度量值

    提示

    在以下代码示例中,我们指定了 SemPy 用于访问该语义模型的工作区。 可以将 Your Workspace 替换为在其中上传语义模型的工作区的名称(在“将语义模型上传到工作区”部分中)。

    df_measures = fabric.list_measures("Customer Profitability Sample", workspace="Your Workspace")
    df_measures
    

    在这里,我们确定 Customer 表是所涉及的表。

  4. 从“Customer Profitability Sample”语义模型中读取“Customer”表

    df_table = fabric.read_table("Customer Profitability Sample", "Customer")
    df_table
    

    注意

    • 数据是使用 XMLA 检索的。 这至少需要启用 XMLA 只读
    • 可检索的数据量受以下因素的限制:- 托管语义模型的容量 SKU 的每次查询的最大内存 - 运行笔记本的 Spark 驱动程序节点(访问节点大小可了解详细信息)
    • 所有请求都使用低优先级来最大程度地减少对 Microsoft Azure Analysis Services 性能的影响,并按交互式请求计费。
  5. 针对每个客户的状态和日期评估“总收入”度量值

    df_measure = fabric.evaluate_measure(
        "Customer Profitability Sample",
        "Total Revenue",
        ["'Customer'[State]", "Calendar[Date]"])
    df_measure
    

    注意

    • 默认情况下,不会使用 XMLA 检索数据,因此不需要启用 XMLA 只读。
    • 数据不受 Power BI 后端限制的约束。
    • 可检索的数据量受以下因素的限制:- 托管语义模型的容量 SKU 的每次查询的最大内存 - 运行笔记本的 Spark 驱动程序节点(访问节点大小可了解详细信息)
    • 所有请求都按交互式请求计费
  6. 若要向度量值计算添加筛选器,请为特定列指定一系列允许值。

    filters = {
        "State[Region]": ["East", "Central"],
        "State[State]": ["FLORIDA", "NEW YORK"]
    }
    df_measure = fabric.evaluate_measure(
        "Customer Profitability Sample",
        "Total Revenue",
        ["Customer[State]", "Calendar[Date]"],
        filters=filters)
    df_measure
    
  7. 你还可以使用 DAX 查询来基于客户的状态和日期评估“总收入”度量值。

    df_dax = fabric.evaluate_dax(
        "Customer Profitability Sample",
        """
        EVALUATE SUMMARIZECOLUMNS(
            'State'[Region],
            'Calendar'[Date].[Year],
            'Calendar'[Date].[Month],
            "Total Revenue",
            CALCULATE([Total Revenue]))
        """)
    

    注意

    • 数据是使用 XMLA 检索的,因此至少需要启用 XMLA 只读
    • 可检索的数据量受 Microsoft Azure Analysis Services 中的可用内存以及 Spark 驱动程序节点(访问节点大小可了解详细信息)的限制
    • 所有请求都使用低优先级来最大程度地减少对 Analysis Services 性能的影响,并按交互式请求计费
  8. 使用 %%dax 单元 magic 来计算相同的 DAX 查询,而无需导入库。 运行此单元以加载 %%dax 单元 magic:

    %load_ext sempy
    

    工作区参数是可选的。 它遵循与 evaluate_dax 函数的工作区参数相同的规则。

    单元 magic 还支持使用 {variable_name} 语法访问 Python 变量。 若要在 DAX 查询中使用大括号,请使用另一个大括号对其进行转义(例如 EVALUATE {{1}})。

    %%dax "Customer Profitability Sample" -w "Your Workspace"
    EVALUATE SUMMARIZECOLUMNS(
        'State'[Region],
        'Calendar'[Date].[Year],
        'Calendar'[Date].[Month],
        "Total Revenue",
        CALCULATE([Total Revenue]))
    

    生成的 FabricDataFrame 可通过 _ 变量获得。 该变量会捕获上次执行的单元的输出。

    df_dax = _
    
    df_dax.head()
    
  9. 你可以将度量值添加到从外部源检索的数据。 此方法整合了三个任务:

    • 它会将列名解析为 Power BI 维度
    • 它将按列来定义分组
    • 它会筛选度量值。任何无法在给定语义模型中解析的列名都将忽略(有关详细信息,请访问支持的 DAX 语法资源)。
    from sempy.fabric import FabricDataFrame
    
    df = FabricDataFrame({
            "Sales Agent": ["Agent 1", "Agent 1", "Agent 2"],
            "Customer[Country/Region]": ["US", "GB", "US"],
            "Industry[Industry]": ["Services", "CPG", "Manufacturing"],
        }
    )
    
    joined_df = df.add_measure("Total Revenue", dataset="Customer Profitability Sample")
    joined_df
    

特殊参数

SemPy read_tableevaluate_measure 方法具有更多可用于操作输出的参数。 这些参数包括:

  • fully_qualified_columns:如果值为“True”,这些方法将以 TableName[ColumnName] 的形式返回列名
  • num_rows:要在结果中输出的行数
  • pandas_convert_dtypes:如果值为“True”,pandas 会将生成的 DataFrame 列转换为可能得最佳 dtype:convert_dtypes。 如果已禁用此参数,则可能导致相关表的列之间出现类型不兼容问题;由于 DAX 隐式类型转换,Power BI 模型可能无法检测到这些问题

SemPy read_table 还使用 Power BI 提供的模型信息。

  • multiindex_hierarchies:如果为“True”,它会将 Power BI 层次结构转换为 pandas MultiIndex 结构

编写可供语义模型使用的数据

添加到湖屋的 Spark 表会自动添加到相应的默认语义模型。 此示例演示如何将数据写入附加的湖屋。 FabricDataFrame 接受与 Pandas 数据帧相同的输入数据。

from sempy.fabric import FabricDataFrame

df_forecast = FabricDataFrame({'ForecastedRevenue': [1, 2, 3]})

df_forecast.to_lakehouse_table("ForecastTable")

通过 Power BI,可以使用湖屋语义模型将 ForecastTable 表添加到复合语义模型