我们都知道在这个数字化转型的世界里,数据测试是多么重要。ETL测试主要包括确保数据已经安全地从源头到目的地的过程。数据处理很容易出错,你可能会因为转型阶段的各种问题而最终导致一些数据丢失、损坏或不相关的数据。这就是为什么ETL测试如此重要的原因:它可以确保一路上没有任何损失或损坏。
为了验证数据,测试人员通常用手写ETL脚本或SQL。脚本将针对源和目的地运行,并对结果进行比较以验证数据。在这篇文章中,我们将看看如何使用Great Expectations、Databricks和C#代码来自动进行数据质量和完整性测试。
伟大的期望和Azure Databricks
Great Expectations是一个共享的、开放的数据质量标准,有助于数据测试。期望是数据断言。在Great Expectations中,它们是工作上的抽象,涵盖了所有类型的常见数据问题。期望是声明性的,可调整的,可扩展的。它们为数据质量提供了一个大型词汇表。
Azure Databricks是一个基于Apache Spark的分析平台,是大数据处理的领先技术之一,由微软和Databricks联合开发。
在本教程中,我们将generic-food_source.csv 作为源数据集,将generic-food_destination.csv 作为 目标数据集。
第1步:在Databricks集群中安装Great Expectations库
- 导航到Azure Databricks --> Compute。
- 选择你想工作的集群。
- 从库中,安装新库 "great-expectations"。
安装成功后,我们可以看到库已成功安装。
第2步:创建一个用于验证数据的笔记本(测试脚本)
假设
为了本教程的目的,我们已经创建了两个数据文件,它们将作为我们案例中的源文件和目标文件。在真实世界的情况下,这些将是各种来源(内部、AWS、GCP等)和目的地。
这两个文件必须上传到Azure Databricks的dbfs文件存储中(使用笔记本中的File->Upload Data选项)。
- 在Databrick工作区创建一个Python笔记本(给笔记本起一个有意义的名字)。
- 将 "great_expectations "和 "pandas "导入第一个单元中。
第3步:创建源数据框和目标数据框,并使用great expectations验证测试
- 创建一个源pandas的数据框架。
- 创建一个目标pandas数据框。
- 将这个pandas数据框转换为Great Expectations数据集,这样我们就可以使用Great Expectations的内置方法验证我们的测试。
- 比较源数据框和目标数据框来验证我们的测试。我们可以在这里利用一组不同的期望断言。
现在你可以看到伟大的期望下的所有可用测试(dataframe.(ctrl+space))。
- 对于目前的实现,我们只是在这里使用一个测试方法进行验证:
expect_table_row_count_to_equal。
这将验证源和目的地之间的行数。
第4步:执行笔记本和验证输出
我们现在已经准备好了我们的测试笔记本,我们需要做的就是从上到下运行每一个单元来获得结果。当你执行最后一个单元时,你将得到如下所示的输出,它将清楚地表明我们的测试是通过还是失败,以及其他一些有用的信息。
这就是了!你刚刚完成了你的一个数据验证,它可以重复使用,每次都能产生预期的结果。
如果你仔细观察,你可以看到"Success":true 的值,它代表我们的测试是否成功。如果计数不匹配,这个函数将返回false 。实际的记录数可以在"observed value" ,实际值(kwargs) 。这不是简单而有效吗?
在Great Expectations库中还有很多期望(断言),你可以自己尝试一下。
创建的笔记本的自动化
现在我们已经在Azure Databricks中创建了一个测试笔记本,我们将从代码层面执行它,并从Databricks中检索结果。我们将使用C#、NUnit和Databricks客户端。
在开始之前,我们必须确定。
- 你的系统中是否安装了Visual Studio?
- 使用我们刚刚开发的笔记本在Azure Databricks中创建一个作业。
- 导航到Azure Databricks--> Workflows。
- 单击 "创建任务"按钮。
- 给出一个任务名称。
- 选择我们已经创建的笔记本路径。
- 从现在起,留下这个字段的其余部分。
- 如果你的测试需要任何特定的输入作为参数,你需要使用底部的添加按钮来添加参数,并将其作为一个键值对。
- 完成所有输入后,点击创建按钮。
- 你将成功创建一个作业。请注意作业的ID,它将是一个长数字。
- 获取ADB的URL,并保存它以备编码之用。
- 转到你的Azure门户-->Azure Databricks服务。
- 转到你的Azure门户-->Azure Databricks服务。
- 从ADB生成一个令牌,用于建立与ADB的连接。生成并保存它。
- 进入Databricks -->Settings-->User Settings。
- 点击生成一个新的令牌-->给一个名称和有效期,然后生成令牌。
- 创建完毕后立即保存。
- 从Azure Databricks获取工作集群的集群ID。
- 进入Databricks-->Compute--> Cluster。
- 点击左侧的JSON。
- 在JSON中找到集群ID[cluster_id]值。
从Visual Studio自动化Databricks测试脚本
第1步:在Visual Studio中创建一个NUnit测试项目
给出一个项目名称和保存项目的位置。
点击 "下一步"按钮,完成该过程。
第2步:安装依赖项
右键单击项目解决方案中的依赖项。
点击管理NuGet包。
搜索 "databricks "并安装Azure Databricks客户端。
一旦安装成功,我们就准备好了所有的依赖项,可以开始编码执行测试了。
第3步:编写脚本和验证测试
一旦你创建了一个NUnit测试项目,你可以看到Visual Studio已经提供了一个测试类和一些测试代码的样本。我们只需要编辑这个测试类文件并添加一些NUnit测试注释来组织代码。
复制并粘贴下面的代码,用你的数据替换参数。
Notebook Path: Azure Databricks笔记本路径JobID**:**这是在先前创建作业过程中保存的。ClusterID: : 我们用来运行作业的集群IDADB 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的测试资源管理器中列出的测试。
这就是你的成果!你已经从Visual Studio自动完成了第一个Azure Databricks测试。你可以通过编写一些测试用例的验证来增加它。
请记住。
- 最初的测试用例执行可能需要一些时间,因为如果集群是空闲的,必须启动。
- 你可以从Visual Studio运行测试,必要时在Azure Databricks中手动检查进度。
- NUnit会生成一个默认的XML报告,供你在报告中利用。