如何使用C#对Azure Databricks进行自动测试

161 阅读7分钟

我们都知道在这个数字化转型的世界里,数据测试是多么重要ETL测试主要包括确保数据已经安全地从源头到目的地的过程。数据处理很容易出错,你可能会因为转型阶段的各种问题而最终导致一些数据丢失、损坏或不相关的数据。这就是为什么ETL测试如此重要的原因:它可以确保一路上没有任何损失或损坏。

为了验证数据,测试人员通常用手写ETL脚本或SQL。脚本将针对源和目的地运行,并对结果进行比较以验证数据。在这篇文章中,我们将看看如何使用Great Expectations、DatabricksC#代码来自动进行数据质量和完整性测试。

伟大的期望和Azure Databricks

Great Expectations是一个共享的、开放的数据质量标准,有助于数据测试。期望是数据断言。在Great Expectations中,它们是工作上的抽象,涵盖了所有类型的常见数据问题。期望是声明性的,可调整的,可扩展的。它们为数据质量提供了一个大型词汇表。 image.png Azure Databricks是一个基于Apache Spark的分析平台,是大数据处理的领先技术之一,由微软和Databricks联合开发。

在本教程中,我们将generic-food_source.csv 作为源数据集,将generic-food_destination.csv 作为 目标数据集。

第1步:在Databricks集群中安装Great Expectations库

  • 导航到Azure Databricks --> Compute。
  • 选择你想工作的集群。
  • 从库中,安装新库 "great-expectations"。 image.png 安装成功后,我们可以看到库已成功安装。 image.png

第2步:创建一个用于验证数据的笔记本(测试脚本)

假设

为了本教程的目的,我们已经创建了两个数据文件,它们将作为我们案例中的源文件和目标文件。在真实世界的情况下,这些将是各种来源(内部、AWS、GCP等)和目的地。

这两个文件必须上传到Azure Databricks的dbfs文件存储中(使用笔记本中的File->Upload Data选项)。

  • 在Databrick工作区创建一个Python笔记本(给笔记本起一个有意义的名字)。
  • 将 "great_expectations "和 "pandas "导入第一个单元中。 image.png

第3步:创建源数据框和目标数据框,并使用great expectations验证测试

  • 创建一个源pandas的数据框架。
  • 创建一个目标pandas数据框。 image.png
  • 将这个pandas数据框转换为Great Expectations数据集,这样我们就可以使用Great Expectations的内置方法验证我们的测试。 image.png
  • 比较源数据框和目标数据框来验证我们的测试。我们可以在这里利用一组不同的期望断言。

现在你可以看到伟大的期望下的所有可用测试(dataframe.(ctrl+space))。 image.png image.png

  • 对于目前的实现,我们只是在这里使用一个测试方法进行验证:expect_table_row_count_to_equal

这将验证源和目的地之间的行数。 image.png

第4步:执行笔记本和验证输出

我们现在已经准备好了我们的测试笔记本,我们需要做的就是从上到下运行每一个单元来获得结果。当你执行最后一个单元时,你将得到如下所示的输出,它将清楚地表明我们的测试是通过还是失败,以及其他一些有用的信息。 image.png 这就是了!你刚刚完成了你的一个数据验证,它可以重复使用,每次都能产生预期的结果。

如果你仔细观察,你可以看到"Success":true 的值,它代表我们的测试是否成功。如果计数不匹配,这个函数将返回false 。实际的记录数可以在"observed value" ,实际值(kwargs) 。这不是简单而有效吗?

在Great Expectations库中还有很多期望(断言),你可以自己尝试一下。

创建的笔记本的自动化

现在我们已经在Azure Databricks中创建了一个测试笔记本,我们将从代码层面执行它,并从Databricks中检索结果。我们将使用C#、NUnit和Databricks客户端。

在开始之前,我们必须确定。

  • 你的系统中是否安装了Visual Studio?
  • 使用我们刚刚开发的笔记本在Azure Databricks中创建一个作业。
    • 导航到Azure Databricks--> Workflows。
    • 单击 "创建任务"按钮。 image.png
    • 给出一个任务名称。
    • 选择我们已经创建的笔记本路径。
    • 从现在起,留下这个字段的其余部分。
    • 如果你的测试需要任何特定的输入作为参数,你需要使用底部的添加按钮来添加参数,并将其作为一个键值对。
    • 完成所有输入后,点击创建按钮。
    • 你将成功创建一个作业。请注意作业的ID,它将是一个长数字。
      image.png image.png
  • 获取ADB的URL,并保存它以备编码之用。
    • 转到你的Azure门户-->Azure Databricks服务。 image.png
  • 从ADB生成一个令牌,用于建立与ADB的连接。生成并保存它。
    • 进入Databricks -->Settings-->User Settings。
    • 点击生成一个新的令牌-->给一个名称和有效期,然后生成令牌。
    • 创建完毕后立即保存。
      image.png image.png
  • 从Azure Databricks获取工作集群的集群ID。
    • 进入Databricks-->Compute--> Cluster。
    • 点击左侧的JSON。
    • 在JSON中找到集群ID[cluster_id]值。
    image.png

从Visual Studio自动化Databricks测试脚本

第1步:在Visual Studio中创建一个NUnit测试项目

image.png 给出一个项目名称和保存项目的位置。 image.png 点击 "下一步"按钮,完成该过程。

第2步:安装依赖项

右键单击项目解决方案中的依赖项。 image.png 点击管理NuGet包

搜索 "databricks "并安装Azure Databricks客户端。 image.png 一旦安装成功,我们就准备好了所有的依赖项,可以开始编码执行测试了。

第3步:编写脚本和验证测试

一旦你创建了一个NUnit测试项目,你可以看到Visual Studio已经提供了一个测试类和一些测试代码的样本。我们只需要编辑这个测试类文件并添加一些NUnit测试注释来组织代码。

复制并粘贴下面的代码,用你的数据替换参数。

  • Notebook Path: Azure Databricks笔记本路径
  • JobID**:**这是在先前创建作业过程中保存的。
  • ClusterID: : 我们用来运行作业的集群ID
  • ADB url: 从Azure Portal->Databricks服务获得的URL。
  • ADB token: 在Azure Databricks中生成的,用于从代码中建立连接。

C#

using Microsoft.Azure.Databricks.Client;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace DataAutomation
{
    public class Tests
    {
        private DatabricksClient? _client;

        [OneTimeSetUp]
        public void Setup()
        {
             _client = DatabricksClient.CreateClient(
                            "ADB url",
                            "ADB token");
        }

        [Test]
        public async Task Count_Validation_Databricks()
        {
            //You need to add parameters here if your notebook requires any.
            //our example we don't have any parameters to pass
            Dictionary<string,string> notebookParametes = new Dictionary<string,string>();
            using (_client)
            {
                //JobName - Give a job name
                //Notebook Path - The notebook path we created in databricks
                //Parameters - Parameters if any -Dictionary 
                //Cluster ID - Which cluster would you like to use for running
                #region Here we create a new notebook job settings.
                var jobSettings = JobSettings.GetNewNotebookJobSettings(
                        "Count_Validation_Test",
                        "/Automation/TestMethods/Great_Expectation_Test"
                        ,notebookParametes).WithExistingCluster("ClusterID");

                await _client.Jobs.Update(JobId, jobSettings);

                #endregion

                //Job id required to get the runid,
                //which will use for polling the job completion
                #region Wait to complete the job run
                var runId = (await _client.Jobs.RunNow(JobId, null)).RunId;
                while (true)
                {
                    var run = await _client.Jobs.RunsGet(runId);

                    Console.WriteLine("[{0:s}] Run Id: {1}\tLifeCycleState: {2}\tStateMessage: {3}",
                        DateTime.UtcNow, runId,
                        run.State.LifeCycleState,
                        run.State.StateMessage);

                    if (run.State.LifeCycleState == RunLifeCycleState.PENDING ||
                        run.State.LifeCycleState == RunLifeCycleState.RUNNING ||
                        run.State.LifeCycleState == RunLifeCycleState.TERMINATING)
                    {
                        await Task.Delay(TimeSpan.FromSeconds(15));
                    }
                    else
                    {
                        break;
                    }
                }
                #endregion



                //pass the runid to get the exit message from notebbok
                #region Get the result from notebook
                var result = (await _client.Jobs.RunsGetOutput(runId)).Item1;

                JObject json = JObject.Parse(result);
                string value = (string)json["success"];


                if (value == "True")
                    Console.WriteLine("Passed");
                else
                    value = "False";
                #endregion

                Assert.AreEqual("True", value);
            }
        }
    }
}

当你传递正确的参数并构建解决方案时,你会看到Visual Studio的测试资源管理器中列出的测试。 image.png 这就是你的成果!你已经从Visual Studio自动完成了第一个Azure Databricks测试。你可以通过编写一些测试用例的验证来增加它。

请记住。

  • 最初的测试用例执行可能需要一些时间,因为如果集群是空闲的,必须启动。
  • 你可以从Visual Studio运行测试,必要时在Azure Databricks中手动检查进度。
  • NUnit会生成一个默认的XML报告,供你在报告中利用。