Инструкция: Проверка данных с помощью SemPy и Great Expectations (GX)

В этом руководстве вы узнаете, как использовать SemPy вместе с Great Expectations (GX) для проверки данных в семантических моделях Power BI.

В этом руководстве показано, как:

  • Проверьте ограничения для набора данных в рабочей области Fabric с помощью источника данных Fabric от Great Expectation (основанного на семантической ссылке).
    • Настройте контекст данных GX, ресурсы данных и ожидания.
    • Просмотр результатов проверки с помощью контрольной точки GX.
  • Используйте семантику для анализа необработанных данных.

Необходимые условия

  • Выберите рабочие области в области навигации слева, чтобы найти и выбрать рабочую область. Эта рабочая область становится текущей рабочей областью.
  • Скачайте пример PBIX.pbix-файла для анализа розничной торговли .
  • В вашем рабочем пространстве выберите Импортировать отчет или отчет с разбивкой на страницы с этого компьютера, чтобы загрузить в рабочую область файл Retail Analysis Sample PBIX.pbix.

Следуйте инструкциям в записной книжке

great_expectations_tutorial.ipynb — это записная книжка, сопровождающая это руководство.

Настройка записной книжки

В этом разделе описана настройка среды записной книжки с необходимыми модулями и данными.

  1. Установите SemPy и соответствующие библиотеки Great Expectations из PyPI с помощью встроенной в ноутбук возможности установки %pip. В этом руководстве намеренно используется набор зависимостей great-expectations<1.0, который соответствует примеру записной книжки Fabric и API GX, используемым в этом примере. Если вы установите новую версию GX в другой среде, некоторые конфигурации и API ожиданий могут отличаться.
# install libraries
%pip install semantic-link 'great-expectations<1.0' great_expectations_experimental great_expectations_zipcode_expectations

# load %%dax cell magic
%load_ext sempy
  1. Выполните необходимые импорты модулей, которые потребуются вам позже:
import great_expectations as gx
from great_expectations.expectations.expectation import ExpectationConfiguration
from great_expectations_zipcode_expectations.expectations import expect_column_values_to_be_valid_zip5

Настройка контекста и источника данных GX

Чтобы приступить к работе с большими ожиданиями, сначала необходимо настроить контекст данных GX. Контекст служит точкой входа для операций GX и содержит все соответствующие конфигурации.

context = gx.get_context()

Теперь вы можете добавить набор данных Fabric в этот контекст в качестве источника данных , чтобы начать взаимодействие с данными. В этом руководстве используется стандартный пример семантической модели Retail Analysis Sample .pbix-файл.

ds = context.sources.add_fabric_powerbi("Retail Analysis Data Source", dataset="Retail Analysis Sample PBIX")

Указание ресурсов данных

Определите ресурсы данных, чтобы указать подмножество данных, с которыми вы хотите работать. Ресурс может быть такими простыми, как целые таблицы, или столь сложными, как пользовательский запрос выражений анализа данных (DAX).

Здесь вы добавите несколько ресурсов:

Таблица Power BI

Добавьте таблицу Power BI в качестве ресурса данных.

ds.add_powerbi_table_asset("Store Asset", table="Store")

Показатель Power BI

Если ваш набор данных содержит предварительно настроенные меры, вы добавляете меры в качестве ресурсов, следуя аналогичному API SemPy evaluate_measure.

ds.add_powerbi_measure_asset(
    "Total Units Asset",
    measure="TotalUnits",
    groupby_columns=["Time[FiscalYear]", "Time[FiscalMonth]"]
)

ДАКС

Если вы хотите определить свои собственные метрики или иметь более широкий контроль над конкретными строками, можно добавить объект DAX с пользовательским запросом DAX. Здесь мы задаем меру Total Units Ratio, разделив две существующие меры.

ds.add_powerbi_dax_asset(
    "Total Units YoY Asset",
    dax_string=
    """
    EVALUATE SUMMARIZECOLUMNS(
        'Time'[FiscalYear],
        'Time'[FiscalMonth],
        "Total Units Ratio", DIVIDE([Total Units This Year], [Total Units Last Year])
    )    
    """
)

Запрос DMV

В некоторых случаях может быть полезным использовать вычисления Dynamic Management View (DMV) как часть процесса проверки данных. Например, можно отслеживать количество нарушений целостности ссылок в наборе данных. Дополнительные сведения см. в разделе "Очистка данных" = более быстрые отчеты.

ds.add_powerbi_dax_asset(
    "Referential Integrity Violation",
    dax_string=
    """
    SELECT
        [Database_name],
        [Dimension_Name],
        [RIVIOLATION_COUNT]
    FROM $SYSTEM.DISCOVER_STORAGE_TABLES
    """
)

Ожидания

Чтобы добавить конкретные ограничения к ресурсам, сначала необходимо настроить наборы ожиданий. После добавления отдельных ожиданий в каждый комплект, вы можете обновить контекст данных, настроенный в начале, используя новую группу. Для полного списка доступных ожиданий см. в Галерее ожиданий GX.

Начните с добавления "Retail Store Suite" с двумя ожиданиями:

  • корректный почтовый индекс
  • таблица с числом строк от 80 до 200
suite_store = context.add_expectation_suite("Retail Store Suite")

suite_store.add_expectation(ExpectationConfiguration("expect_column_values_to_be_valid_zip5", { "column": "PostalCode" }))
suite_store.add_expectation(ExpectationConfiguration("expect_table_row_count_to_be_between", { "min_value": 80, "max_value": 200 }))

context.add_or_update_expectation_suite(expectation_suite=suite_store)

TotalUnits Измерения

Добавьте "Retail Measure Suite" с одним условием:

  • Значения столбцов должны превышать 50 000
suite_measure = context.add_expectation_suite("Retail Measure Suite")
suite_measure.add_expectation(ExpectationConfiguration(
    "expect_column_values_to_be_between", 
    {
        "column": "TotalUnits",
        "min_value": 50000
    }
))

context.add_or_update_expectation_suite(expectation_suite=suite_measure)

Total Units Ratio ДАКС

Добавьте "Retail DAX Suite" с одним условием:

  • Значения столбцов для общего числа единиц должны составлять от 0,8 до 1,5.
suite_dax = context.add_expectation_suite("Retail DAX Suite")
suite_dax.add_expectation(ExpectationConfiguration(
    "expect_column_values_to_be_between", 
    {
        "column": "[Total Units Ratio]",
        "min_value": 0.8,
        "max_value": 1.5
    }
))

context.add_or_update_expectation_suite(expectation_suite=suite_dax)

Нарушения целостности ссылок (DMV)

Добавьте "Retail DMV Suite" с одним ожиданием:

  • Значение RIVIOLATION_COUNT должно равняться 0.
suite_dmv = context.add_expectation_suite("Retail DMV Suite")
# There should be no RI violations
suite_dmv.add_expectation(ExpectationConfiguration(
    "expect_column_values_to_be_in_set", 
    {
        "column": "RIVIOLATION_COUNT",
        "value_set": [0]
    }
))
context.add_or_update_expectation_suite(expectation_suite=suite_dmv)

Ратификация

Чтобы фактически выполнить указанные ожидания для данных, сначала создайте контрольную точку и добавьте её в контекст. Дополнительные сведения о конфигурации контрольных точек см. в рабочем процессе проверки данных.

checkpoint_config = {
    "name": f"Retail Analysis Checkpoint",
    "validations": [
        {
            "expectation_suite_name": "Retail Store Suite",
            "batch_request": {
                "datasource_name": "Retail Analysis Data Source",
                "data_asset_name": "Store Asset",
            },
        },
        {
            "expectation_suite_name": "Retail Measure Suite",
            "batch_request": {
                "datasource_name": "Retail Analysis Data Source",
                "data_asset_name": "Total Units Asset",
            },
        },
        {
            "expectation_suite_name": "Retail DAX Suite",
            "batch_request": {
                "datasource_name": "Retail Analysis Data Source",
                "data_asset_name": "Total Units YoY Asset",
            },
        },
        {
            "expectation_suite_name": "Retail DMV Suite",
            "batch_request": {
                "datasource_name": "Retail Analysis Data Source",
                "data_asset_name": "Referential Integrity Violation",
            },
        },
    ],
}
checkpoint = context.add_checkpoint(
    **checkpoint_config
)

Теперь запустите контрольную точку и извлеките результаты в виде pandas DataFrame для простого форматирования.

result = checkpoint.run()

Обработка и печать результатов.

import pandas as pd

data = []

for run_result in result.run_results:
    for validation_result in result.run_results[run_result]["validation_result"]["results"]:
        row = {
            "Batch ID": run_result.batch_identifier,
            "type": validation_result.expectation_config.expectation_type,
            "success": validation_result.success
        }

        row.update(dict(validation_result.result))
        
        data.append(row)

result_df = pd.DataFrame.from_records(data)    

result_df[["Batch ID", "type", "success", "element_count", "unexpected_count", "partial_unexpected_list"]]

в таблице показаны результаты проверки.

Из этих результатов видно, что все ваши ожидания прошли валидацию, за исключением ожидания «Total Units YoY Asset», который вы определили через пользовательский запрос DAX. Этот отказ ожидается в образце и полезен для демонстрации диагностического процесса в следующем разделе.

Диагностика

С помощью семантической ссылки можно получить исходные данные, чтобы понять, какие точные годы находятся вне диапазона. Семантическая ссылка предоставляет встроенную магию для выполнения запросов DAX. Используйте семантическую ссылку, чтобы выполнить тот же запрос, который вы передали в ресурс данных GX, и визуализировать полученные значения.

%%dax "Retail Analysis Sample PBIX"

EVALUATE SUMMARIZECOLUMNS(
    'Time'[FiscalYear],
    'Time'[FiscalMonth],
    "Total Units Ratio", DIVIDE([Total Units This Year], [Total Units Last Year])
)

в таблице показаны результаты сводных данных запроса DAX.

Сохраните эти результаты в DataFrame.

df = _

Постройте график результатов.

import matplotlib.pyplot as plt

df["Total Units % Change YoY"] = (df["[Total Units Ratio]"] - 1)

df.set_index(["Time[FiscalYear]", "Time[FiscalMonth]"]).plot.bar(y="Total Units % Change YoY")

plt.axhline(0)

plt.axhline(-0.2, color="red", linestyle="dotted")
plt.axhline( 0.5, color="red", linestyle="dotted")

None

График показывает результаты суммирования запроса DAX.

На графике видно, что апрель и июль были немного наружи диапазона, и затем можно предпринять дальнейшие шаги для расследования.

Хранение конфигурации GX

По мере изменения данных в наборе данных с течением времени может потребоваться повторно выполнить только что выполненные проверки GX. В настоящее время контекст данных (содержащий подключенные ресурсы данных, наборы ожиданий и контрольную точку) существует временно, но его можно преобразовать в файловый контекст для дальнейшего использования. Кроме того, можно создать экземпляр контекста файла (см. создание экземпляра контекста данных).

context = context.convert_to_file_context()

Теперь, когда вы сохранили контекст, скопируйте каталог gx в lakehouse.

Important

В этой ячейке предполагается, что вы добавили lakehouse в блокнот. Если вы не прикрепите дом у озера, ошибки не будет, но и потом не сможете получить контекст. Если добавить Lakehouse сейчас, ядро перезагружается, и вам придётся заново запускать весь ноутбук, чтобы вернуться к этому моменту.

# copy GX directory to attached lakehouse
!cp -r gx/ /lakehouse/default/Files/gx

Теперь будущие контексты можно создать с помощью context = gx.get_context(project_root_dir="<your path here>"), чтобы использовать все конфигурации из этого руководства.

Например, в новой записной книжке подключите то же озеро и используйте context = gx.get_context(project_root_dir="/lakehouse/default/Files/gx") для извлечения контекста.

Ознакомьтесь с другими руководствами по семантической ссылке / SemPy: