Saltar al contenido principal
Tiempo de leer: 5 minutos

En una publicación anterior, presenté algunos usos posibles de python como una herramienta externa para Power BI Desktop y pasé por la configuración principal. Esta publicación amplía la configuración básica de la herramienta externa que se encuentra en la Parte 2.

Hay dos objetivos para esta publicación:
1) Muestre cómo ejecutar un script de python dentro de un entorno virtual
2) Conéctese a una biblioteca .NET llamada Modelo de objetos tabulares (TOM) para obtener datos sobre un modelo de datos de Power BI Desktop actualmente abierto

Modificar [tool].pbitool.json para ejecutarse en un entorno python

La parte 2 mostró cómo ejecutar python.exe y ejecutar un script .py, pero no se ejecutó en un entorno. Esta limitación permite scripts básicos, pero los scripts más complejos usan código de otros módulos y paquetes.

Para ampliar el ejemplo básico que se encuentra en la Parte 2, creé una muestra [tool]Archivo .pbitool.json (esencia) que muestra cómo ejecutar una secuencia de comandos de python en un entorno determinado.

Entorno base (raíz)

Estoy usando Anaconda, que tiene un base ubicación del entorno de C: ProgramData Anaconda3.

{
  "version": "1.0",
  "name": "PyTOM",
  "description": "Use python with Tabular Object Model",
  "path": "C:ProgramDataAnaconda3python.exe",
  "arguments": "C:/ProgramData/Anaconda3/cwp.py C:/ProgramData/Anaconda3 C:ProgramDataAnaconda3python.exe C:/[PATH TO PYTHON SCRIPT].py "%server%" "%database%"",
  "iconData": ""
} 

Tenga en cuenta que no es necesario cambiar nada con respecto al ejemplo de la Parte 2, excepto por la adición de algunos argumentos antes del script principal de python, el servidor y los valores de la base de datos. Esto me tomó algo de tiempo para trabajar con un lote de prueba y error, ¡así que presta atención!

igraal_es-es

¿Que cambios?

  1. El núcleo camino sigue siendo su python.exe
  2. En lugar de ejecutar primero la secuencia de comandos deseada, los argumentos definen cwp.py primero, luego la ubicación de su entorno, luego otro python.exe (probé muchas variaciones pero nunca logré que funcionara correctamente sin esta estructura).
  3. Después de esa secuencia, los argumentos continúan con su script principal y las referencias de herramientas externas de Power BI para el servidor y la base de datos.

Entorno virtual con nombre

Para un entorno virtual aparte de la base, necesita modificar los argumentos para usar el entorno correcto. Esto garantiza que los paquetes correctos que forman parte de ese entorno estén disponibles para usar con su script de Power BI.

Aquí hay un ejemplo de un entorno conda llamado PowerBI. Tenga en cuenta que la ubicación de python.exe no tener cambiar al entorno conda (aunque podría hacerlo), pero cambiar la parte del entorno del argumento es fundamental.

{
  "version": "1.0",
  "name": "PyTOM",
  "description": "Use python with Tabular Object Model",
  "path": "C:ProgramDataAnaconda3python.exe",
  "arguments": "C:/ProgramData/Anaconda3/cwp.py  C:/Users/DavidEldersveld/.conda/envs/PowerBI C:ProgramDataAnaconda3python.exe C:/[PATH TO PYTHON SCRIPT].py "%server%" "%database%"",
  "iconData": ""
} 

Conectarse a TOM

los Modelo de objeto tabular La biblioteca (TOM) para .NET abre el modelo de datos de Power BI a herramientas externas. Se requieren dos piezas para permitir que python interactúe con .NET:
1) Pythonnet paquete para .NET CLR (pip install pythonnet)
2) python-SSAS módulo (ssas_api.py ubicado en la misma carpeta que el script principal que desea ejecutar)

los python-ssas (ssas_api.py) El módulo python que facilita la conexión TOM es todo el trabajo de Josh Dimarsky, originalmente para consultar y procesar Analysis Services. Simplemente lo reutilicé para usarlo con Power BI Desktop o el punto final XMLA en Power BI Premium y lo extendí con algunos ejemplos relevantes. Todo se basa en el módulo python de Josh, que tiene funciones para conectarse a TOM, ejecutar consultas DAX, etc.

Este módulo en particular es solo uno posible forma de utilizar .NET CLR con python. Por ejemplo, puede probar alternativas como .NetBridge para ejecutar el pyDotNet empaquete y codifique su propia solución para acceder a la DLL de TOM. No he hecho un inventario de los diferentes métodos disponibles para saber cuál es el mejor o el más eficiente. Sin embargo, el módulo ssas_api.py funcionó directamente para lo que necesitaba, así que me quedé con él.

Siempre que Power BI Desktop esté instalado, no debería tener que obtener manualmente las DLL necesarias. Podrías conseguirlos de Microsoft directamente aunque si es necesario.

El código de Josh en ssas_api.py carga Microsoft.AnalysisServices.Tabular.dll y Microsoft.AnalysisServices.AdomdClient.dll del GAC.

image-8-6308357

Obtener metadatos del modelo de Power BI de TOM

Con los diversos requisitos previos establecidos, puede codificar contra TOM. El código completo está al final de esta publicación y esta esencia, pero los elementos principales en las primeras 32 líneas:
1) importar el ssas_api.py módulo
2) defina una conexión al modelo de Power BI Desktop usando el servidor argumento pasado al hacer clic en el icono en Herramientas externas (conn = «Proveedor = MSOLAP; Fuente de datos =» + str (sys.argv[1]) + «; Catálogo inicial =»; » )
3) defina una consulta DAX «falsa» que ayude a cargar .NET (dax_string = ‘EVALUATE ROW («Cargando ensamblados .NET», 1)’
4) ejecuta la consulta DAX (df = powerbi.get_DAX (connection_string = conn, dax_string = dax_string)
5) completa las importaciones de TOM y AMOMD para python una vez que se cargan y se conecta a TOM

global System, DataTable, AMO, ADOMD

import System
from System.Data import DataTable
import Microsoft.AnalysisServices.Tabular as TOM
import Microsoft.AnalysisServices.AdomdClient as ADOMD

TOMServer = TOM.Server()
TOMServer.Connect(conn) 

Una vez conectado al modelo, el resto de mi secuencia de comandos python de muestra muestra cómo cargar varios objetos de los metadatos del modelo en pandas DataFrames. Solo está destinado a ser una muestra para ilustrar lo que podría ser posible, pero podría ampliarse para documentar todos los metadatos disponibles si se desea.

image-9-2985989

Próximamente en la parte 4: uso de Jupyter y ejecución de DAX

En la parte 4, verá cómo crear un cuaderno de Jupyter con la información de conexión de Power BI disponible.

Es posible que también haya notado get_DAX función utilizada anteriormente para ayudar a cargar los ensamblados .NET requeridos. Sin embargo, es mucho más poderoso que lo que se muestra aquí. Puede evaluar cualquier consulta DAX que desee escribir manualmente, copiar y pegar fuera de Power BI Desktop Analizador de rendimientoo copie y pegue de Estudio DAX.

Como se vio en la Parte 1, las ventajas y los escenarios imaginativos de usar python con Power BI comienzan a aumentar con la capacidad de ejecutar DAX desde python.

************************************************ **********************

FULL CODE for PowerBITOMSample.py 
import sys

import ssas_api as powerbi
import pandas as pd

print("Hit Enter to connect and say 'Hi TOM!'")
input()

print('Power BI Desktop Connection')
print(str(sys.argv[1]))
print(str(sys.argv[2]))

conn = "Provider=MSOLAP;Data Source=" + str(sys.argv[1]) + ";Initial Catalog='';"
print(conn)
print()

dax_string = 'EVALUATE ROW("Loading .NET assemblies",1)'
df = powerbi.get_DAX(connection_string=conn, dax_string=dax_string)

print("Crossing the streams...")
global System, DataTable, AMO, ADOMD

import System
from System.Data import DataTable
import Microsoft.AnalysisServices.Tabular as TOM
import Microsoft.AnalysisServices.AdomdClient as ADOMD

print("Reticulating splines...")
print()

TOMServer = TOM.Server()
TOMServer.Connect(conn)

print("Hi TOM...")
print()

# Database info
for item in TOMServer.Databases:
    print("Database: ", item.Name)
    print("Compatibility Level: ", item.CompatibilityLevel) 
    print("Created: ", item.CreatedTimestamp)

DatabaseId = str(sys.argv[2])
PowerBIDatabase = TOMServer.Databases[DatabaseId]

print()

# Define measure dataframe
dfMeasures = pd.DataFrame(
    columns=['Table',
             'Name', 
             'Description', 
             'DataType', 
             'DataCategory',
             'Expression',
             'FormatString',
             'DisplayFolder',
             'Implicit',
             'Hidden',
             'ModifiedTime',
             'State'])

# Define column dataframe
dfColumns = pd.DataFrame(
    columns=['Table',
             'Name'])

# Tables
print("Listing tables...")
for table in PowerBIDatabase.Model.Tables:
    print(table.Name)

    # Assign current table by name
    CurrentTable = PowerBIDatabase.Model.Tables.Find(table.Name)

    # print(type(CurrentTable))
    # print(type(CurrentTable.Measures))

    # Measures
    for measure in CurrentTable.Measures:
        new_row = {'Table':table.Name,
                'Name':measure.Name, 
                'Description':measure.Description, 
                'DataType':measure.DataType,
                'DataCategory':measure.DataCategory,
                'Expression':measure.Expression,
                'FormatString':measure.FormatString,
                'DisplayFolder':measure.DisplayFolder,
                'Implicit':measure.IsSimpleMeasure,
                'Hidden':measure.IsHidden,
                'ModifiedTime':measure.ModifiedTime,
                'State':measure.State}
        #print(new_row)
        dfMeasures = dfMeasures.append(new_row, ignore_index=True)

    # Columns
    for column in CurrentTable.Columns:
        new_row = {'Table':table.Name,
                'Name':column.Name}
        #print(column.Name)
        dfColumns = dfColumns.append(new_row, ignore_index=True)

print(dfMeasures)
print(dfColumns)

input()

Enlaces de pago

Como Asociado de Amazon, gano con las compras que califican.