{ "cells": [ { "cell_type": "markdown", "id": "5c27dfd1-4fe0-4a97-92e6-ddf78889aa93", "metadata": { "nteract": { "transient": { "deleting": false } } }, "source": [ "### Install the latest .whl package\n", "\n", "Check [here](https://pypi.org/project/semantic-link-labs/) to see the latest version." ] }, { "cell_type": "code", "execution_count": null, "id": "d5cae9db-cef9-48a8-a351-9c5fcc99645c", "metadata": { "jupyter": { "outputs_hidden": true, "source_hidden": false }, "nteract": { "transient": { "deleting": false } } }, "outputs": [], "source": [ "%pip install semantic-link-labs" ] }, { "cell_type": "markdown", "id": "5a3fe6e8-b8aa-4447-812b-7931831e07fe", "metadata": { "nteract": { "transient": { "deleting": false } } }, "source": [ "### Connect to the [Tabular Object Model](https://learn.microsoft.com/analysis-services/tom/introduction-to-the-tabular-object-model-tom-in-analysis-services-amo?view=asallproducts-allversions) ([TOM](https://learn.microsoft.com/dotnet/api/microsoft.analysisservices.tabular.model?view=analysisservices-dotnet))\n", "Setting the 'readonly' property to False enables read/write mode. This allows changes to be made to the semantic model." ] }, { "cell_type": "code", "execution_count": null, "id": "cde43b47-4ecc-46ae-9125-9674819c7eab", "metadata": { "jupyter": { "outputs_hidden": false, "source_hidden": false }, "nteract": { "transient": { "deleting": false } } }, "outputs": [], "source": [ "import sempy_labs as labs\n", "from sempy_labs.tom import connect_semantic_model\n", "\n", "dataset = '' # Enter dataset name\n", "workspace = None # Enter workspace name\n", "\n", "with connect_semantic_model(dataset=dataset, readonly=True, workspace=workspace) as tom:\n", " for t in tom.model.Tables:\n", " print(t.Name)" ] }, { "cell_type": "markdown", "id": "45dc24ac", "metadata": {}, "source": [ "### Connect to the Tabular Object Model using a Service Principal (also supports connecting to Azure Analysis Services)" ] }, { "cell_type": "code", "execution_count": null, "id": "4054afa5", "metadata": {}, "outputs": [], "source": [ "key_vault_uri = '' # Enter your key vault URI\n", "key_vault_tenant_id = '' # Enter the key vault key to the secret storing your Tenant ID\n", "key_vault_client_id = '' # Enter the key vault key to the secret storing your Client ID (Application ID)\n", "key_vault_client_secret = '' # Enter the key vault key to the secret storing your Client Secret" ] }, { "cell_type": "code", "execution_count": null, "id": "1a94c1ad", "metadata": {}, "outputs": [], "source": [ "dataset = '' # Enter dataset name\n", "workspace = None # Enter workspace name (for Azure Analysis Serivces instance use this format: \"asazure://.asazure.windows.net/\")\n", "\n", "with labs.service_principal_authentication(\n", " key_vault_uri=key_vault_uri, \n", " key_vault_tenant_id=key_vault_tenant_id,\n", " key_vault_client_id=key_vault_client_id,\n", " key_vault_client_secret=key_vault_client_secret):\n", "\n", " with connect_semantic_model(dataset=dataset, workspace=workspace, readonly=True) as tom:\n", " for t in tom.model.Tables:\n", " print(t.Name)" ] }, { "cell_type": "markdown", "id": "fc6b277e", "metadata": {}, "source": [ "### Make changes to a semantic model using custom functions\n", "Note that the custom functions have additional optional parameters (which may not be used in the examples below) for adding properties to model objects. Check the [documentation](https://semantic-link-labs.readthedocs.io/en/0.5.0/sempy_labs.tom.html) to see all available parameters for each function." ] }, { "cell_type": "markdown", "id": "6d46d878", "metadata": {}, "source": [ "#### Rename objects in the semantic model" ] }, { "cell_type": "code", "execution_count": null, "id": "1284825a", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " for t in tom.model.Tables:\n", " t.Name = t.Name.replace('_',' ')\n" ] }, { "cell_type": "code", "execution_count": null, "id": "d3b60303", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " for c in tom.all_columns():\n", " c.Name = c.Name.replace('_',' ')" ] }, { "cell_type": "markdown", "id": "402a477c", "metadata": {}, "source": [ "#### Add measure(s) to the semantic model" ] }, { "cell_type": "code", "execution_count": null, "id": "bdaaaa5c", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " tom.add_measure(table_name='Internet Sales', measure_name='Sales Amount', expression=\"SUM('Internet Sales'[SalesAmount])\")\n", " tom.add_measure(table_name='Internet Sales', measure_name='Order Quantity', expression=\"SUM('Internet Sales'[OrderQty])\") " ] }, { "cell_type": "code", "execution_count": null, "id": "a53a544b", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " for t in tom.model.Tables:\n", " if t.Name == 'Internet Sales':\n", " tom.add_measure(table_name=t.Name, measure_name='Sales Amount', expression=\"SUM('Internet Sales'[SalesAmount])\")\n", " tom.add_measure(table_name=t.Name, measure_name='Order Quantity', expression=\"SUM('Internet Sales'[OrderQty])\")" ] }, { "cell_type": "markdown", "id": "1cb1632f", "metadata": {}, "source": [ "#### Add column(s) to the semantic model" ] }, { "cell_type": "code", "execution_count": null, "id": "81a22749", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " tom.add_data_column(table_name='Product', column_name='Size Range', source_column='SizeRange', data_type='Int64')\n", " tom.add_data_column(table_name= 'Segment', column_name='Summary Segment', source_column='SummarySegment', data_type='String')\n", "\n", " tom.add_calculated_column(table_name='Internet Sales', column_name='GrossMargin', expression=\"'Internet Sales'[SalesAmount] - 'Internet Sales'[ProductCost]\", data_type='Decimal')" ] }, { "cell_type": "code", "execution_count": null, "id": "053b6516", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " for t in tom.model.Tables:\n", " if t.Name == 'Product':\n", " tom.add_data_column(table_name=t.Name, column_name='Size Range', source_column='SizeRange', data_type='Int64')\n", " elif t.Name == 'Segment':\n", " tom.add_data_column(table_name = t.Name, column_name='Summary Segment', source_column='SummarySegment', data_type='String')\n", " elif t.Name == 'Internet Sales':\n", " tom.add_calculated_column(table_name=t.Name, column_name='GrossMargin', expression=\"'Internet Sales'[SalesAmount] - 'Internet Sales'[ProductCost]\", data_type='Decimal')" ] }, { "cell_type": "markdown", "id": "f53dcca7", "metadata": {}, "source": [ "#### Add hierarchies to the semantic model" ] }, { "cell_type": "code", "execution_count": null, "id": "a9309e23", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " tom.add_hierarchy(table_name='Geography', hierarchy_name='Geo Hierarchy', levels=['Continent', 'Country', 'State', 'City'])" ] }, { "cell_type": "code", "execution_count": null, "id": "a04281ce", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " for t in tom.model.Tables:\n", " if t.Name == 'Geography':\n", " tom.add_hierarchy(table_name=t.Name, hierarchy_name='Geo Hierarchy', levels=['Continent', 'Country', 'State', 'City'])" ] }, { "cell_type": "markdown", "id": "47c06a4f", "metadata": {}, "source": [ "#### Add relationship(s) to the semantic model" ] }, { "cell_type": "code", "execution_count": null, "id": "e8cd7bbf", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " tom.add_relationship(\n", " from_table='Internet Sales', from_column='ProductKey',\n", " to_table='Product', to_column ='ProductKey', \n", " from_cardinality='Many', to_cardinality='One')" ] }, { "cell_type": "markdown", "id": "3cc7f11e", "metadata": {}, "source": [ "#### Add a table with an M partition to a semantic model" ] }, { "cell_type": "code", "execution_count": null, "id": "0f5dd66a", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " table_name='Sales'\n", " tom.add_table(name=table_name)\n", " tom.add_m_partition(table_name=table_name, partition_name=table_name, expression='let....')" ] }, { "cell_type": "markdown", "id": "ea389123", "metadata": {}, "source": [ "#### Add a table with an entity partition to a Direct Lake semantic model " ] }, { "cell_type": "code", "execution_count": null, "id": "f75387d1", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " table_name = 'Sales'\n", " tom.add_table(name=table_name)\n", " tom.add_entity_partition(table_name=table_name, entity_name=table_name)" ] }, { "cell_type": "markdown", "id": "e74d0f54", "metadata": {}, "source": [ "#### Add a calculated table (and columns) to a semantic model" ] }, { "cell_type": "code", "execution_count": null, "id": "934f7315", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " table_name = 'Sales'\n", " tom.add_calculated_table(name=table_name, expression=\"DISTINCT('Product'[Color])\")\n", " tom.add_calculated_table_column(table_name=table_name, column_name='Color', source_column=\"'Product[Color]\", data_type='String')" ] }, { "cell_type": "markdown", "id": "0e7088b7", "metadata": {}, "source": [ "#### Add role(s) to the semantic model" ] }, { "cell_type": "code", "execution_count": null, "id": "ad60ebb9", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " tom.add_role(role_name='Reader')" ] }, { "cell_type": "markdown", "id": "c541f81a", "metadata": {}, "source": [ "#### Set row level security (RLS) to the semantic model\n", "This adds row level security (or updates it if it already exists)" ] }, { "cell_type": "code", "execution_count": null, "id": "98603a08", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " tom.set_rls(\n", " role_name='Reader', \n", " table_name='Product',\n", " filter_expression=\"'Dim Product'[Color] = \\\"Blue\\\"\"\n", " )" ] }, { "cell_type": "code", "execution_count": null, "id": "effea009", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " for r in tom.model.Roles:\n", " if r.Name == 'Reader':\n", " tom.set_rls(role_name=r.Name, table_name='Product', filter_expression=\"'Dim Product'[Color] = \\\"Blue\\\"\")" ] }, { "cell_type": "markdown", "id": "7fa7a03c", "metadata": {}, "source": [ "#### Set object level security (OLS) to the semantic model\n", "This adds row level security (or updates it if it already exists)" ] }, { "cell_type": "code", "execution_count": null, "id": "dd0def9d", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " tom.set_ols(role_name='Reader', table_name='Product', column_name='Size', permission='None')" ] }, { "cell_type": "code", "execution_count": null, "id": "7a389dc7", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " for r in tom.model.Roles:\n", " if r.Name == 'Reader':\n", " for t in tom.model.Tables:\n", " if t.Name == 'Product':\n", " tom.set_ols(role_name=r.Name, table_name=t.Name, column_name='Size', permission='None')" ] }, { "cell_type": "markdown", "id": "d0f7ccd1", "metadata": {}, "source": [ "#### Add calculation groups and calculation items to the semantic model" ] }, { "cell_type": "code", "execution_count": null, "id": "97f4708b", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " tom.add_calculation_group(name='MyCalcGroup')" ] }, { "cell_type": "code", "execution_count": null, "id": "fef68832", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " tom.add_calculation_item(table_name='MyCalcGroup', calculation_item_name='YTD', expression=\"CALCULATE(SELECTEDMEASURE(), DATESYTD('Calendar'[CalendarDate]))\")\n", " tom.add_calculation_item(table_name='MyCalcGroup', calculation_item_name='MTD', expression=\"CALCULATE(SELECTEDMEASURE(), DATESMTD('Calendar'[CalendarDate]))\")" ] }, { "cell_type": "code", "execution_count": null, "id": "c7653dcc", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " for t in tom.model.Tables:\n", " if t.Name == 'MyCalcGroup':\n", " tom.add_calculation_item(table_name=t.Name, calculation_item_name='YTD', expression=\"CALCULATE(SELECTEDMEASURE(), DATESYTD('Calendar'[CalendarDate]))\")\n", " tom.add_calculation_item(table_name=t.Name, calculation_item_name='MTD', expression=\"CALCULATE(SELECTEDMEASURE(), DATESMTD('Calendar'[CalendarDate]))\")" ] }, { "cell_type": "markdown", "id": "c6450c74", "metadata": {}, "source": [ "#### Add translations to a semantic model" ] }, { "cell_type": "code", "execution_count": null, "id": "2b616b90", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " tom.add_translation(language='it-IT')" ] }, { "cell_type": "code", "execution_count": null, "id": "dc24c200", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " tom.set_translation(object = tom.model.Tables['Product'], language='it-IT', property='Name', value='Produtto')" ] }, { "cell_type": "markdown", "id": "3048cc95", "metadata": {}, "source": [ "#### Add a [Field Parameter](https://learn.microsoft.com/power-bi/create-reports/power-bi-field-parameters) to a semantic model" ] }, { "cell_type": "code", "execution_count": null, "id": "0a94af94", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " tom.add_field_parameter(table_name='Parameter', objects=\"'Product'[Color], [Sales Amount], 'Geography'[Country]\")" ] }, { "cell_type": "markdown", "id": "95aac09a", "metadata": {}, "source": [ "#### Remove an object(s) from a semantic model" ] }, { "cell_type": "code", "execution_count": null, "id": "1e2572a8", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " for t in tom.model.Tables:\n", " if t.Name == 'Product':\n", " tom.remove_object(object=t.Columns['Size'])\n", " tom.remove_object(object=t.Hierarchies['Product Hierarchy'])" ] }, { "cell_type": "code", "execution_count": null, "id": "bc453177", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " tom.remove_object(object=tom.model.Tables['Product'].Columns['Size'])\n", " tom.remove_object(object=tom.model.Tables['Product'].Hierarchies['Product Hierarchy'])" ] }, { "cell_type": "markdown", "id": "e0d0cb9e", "metadata": {}, "source": [ "### Custom functions to loop through non-top-level objects in a semantic model" ] }, { "cell_type": "code", "execution_count": null, "id": "cbe3b1a3", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=True, workspace=workspace) as tom:\n", " for c in tom.all_columns():\n", " print(c.Name)" ] }, { "cell_type": "code", "execution_count": null, "id": "3f643e66", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=True, workspace=workspace) as tom:\n", " for m in tom.all_measures():\n", " print(m.Name)" ] }, { "cell_type": "code", "execution_count": null, "id": "ed1cde0f", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=True, workspace=workspace) as tom:\n", " for p in tom.all_partitions():\n", " print(p.Name)" ] }, { "cell_type": "code", "execution_count": null, "id": "f48014ae", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=True, workspace=workspace) as tom:\n", " for h in tom.all_hierarchies():\n", " print(h.Name)" ] }, { "cell_type": "code", "execution_count": null, "id": "9f5e7b72", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=True, workspace=workspace) as tom:\n", " for ci in tom.all_calculation_items():\n", " print(ci.Name)" ] }, { "cell_type": "code", "execution_count": null, "id": "3cd9ebc1", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=True, workspace=workspace) as tom:\n", " for l in tom.all_levels():\n", " print(l.Name)" ] }, { "cell_type": "code", "execution_count": null, "id": "12c58bad", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " for rls in tom.all_rls():\n", " print(rls.Name)" ] }, { "cell_type": "markdown", "id": "1a294bd2", "metadata": {}, "source": [ "### See Vertipaq Analyzer stats" ] }, { "cell_type": "code", "execution_count": null, "id": "469660e9", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=False, workspace=workspace) as tom:\n", " tom.set_vertipaq_annotations()\n", "\n", " for t in tom.model.Tables:\n", " rc = tom.row_count(object = t)\n", " print(f\"{t.Name} : {str(rc)}\")\n", " for c in t.Columns:\n", " col_size = tom.total_size(object=c)\n", " print(labs.format_dax_object_name(t.Name, c.Name) + ' : ' + str(col_size))" ] }, { "cell_type": "markdown", "id": "1ab26dfd", "metadata": {}, "source": [ "### 'UsedIn' functions" ] }, { "cell_type": "code", "execution_count": null, "id": "412bf287", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=True, workspace=workspace) as tom:\n", " for c in tom.all_columns():\n", " full_name = labs.format_dax_object_name(c.Parent.Name, c.Name)\n", " for h in tom.used_in_hierarchies(column = c):\n", " print(f\"{full_name} : {h.Name}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "76556900", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=True, workspace=workspace) as tom:\n", " for c in tom.all_columns():\n", " full_name = labs.format_dax_object_name(c.Parent.Name, c.Name)\n", " for r in tom.used_in_relationships(object = c):\n", " rel_name = labs.create_relationship_name(r.FromTable.Name, r.FromColumn.Name, r.ToTable.Name, r.ToColumn.Name)\n", " print(f\"{full_name} : {rel_name}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "4d9ec24e", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=True, workspace=workspace) as tom:\n", " for t in tom.model.Tables:\n", " for r in tom.used_in_relationships(object = t):\n", " rel_name = labs.create_relationship_name(r.FromTable.Name, r.FromColumn.Name, r.ToTable.Name, r.ToColumn.Name)\n", " print(f\"{t.Name} : {rel_name}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "82251336", "metadata": {}, "outputs": [], "source": [ "with connect_semantic_model(dataset=dataset, readonly=True, workspace=workspace) as tom:\n", " dep = labs.get_model_calc_dependencies(dataset = dataset, workspace=workspace)\n", " for o in tom.used_in_rls(object = tom.model.Tables['Product'].Columns['Color'], dependencies=dep):\n", " print(o.Name)" ] } ], "metadata": { "kernel_info": { "name": "synapse_pyspark" }, "kernelspec": { "display_name": "Synapse PySpark", "language": "Python", "name": "synapse_pyspark" }, "language_info": { "name": "python" }, "microsoft": { "language": "python" }, "nteract": { "version": "nteract-front-end@1.0.0" }, "spark_compute": { "compute_id": "/trident/default" }, "synapse_widget": { "state": {}, "version": "0.1" }, "widgets": {} }, "nbformat": 4, "nbformat_minor": 5 }