Metric 是 Datavines 中一个核心概念,一个 Metric 表示一个数据质量检查规则,比如空值检查和表行数检查都是一个规则。Metric 采用插件化设计,用户可以根据自己的需求来实现一个 Metric。下面我们来详细讲解一下如何自定义Metric

第一步

我们先了解下几个接口和抽象类,它们是实现自定义 Metric 的关键。

SqlMetric 接口

SqlMetric接口中定义了规则的各种属性和操作的接口。

@SPI
public interface SqlMetric {
// 中文名
String getName();
// 英文名
String getZhName();
// 根据系统的语言进行名字返回
default String getNameByLanguage(boolean isEn) {
return isEn ? getName() : getZhName();
}
// 规则属于哪个维度,比如准确性、唯一性等等
MetricDimension getDimension();
// 规则的类型,包括单表检查、单表自定义检查
MetricType getType();
// 规则的级别,比如表级别、列级别
default MetricLevel getLevel() {
return MetricLevel.NONE;
}
// 是否支持错误数据输出
boolean isInvalidateItemsCanOutput(); /**
* 获取不符合规则的数据的SQL语句
* @return ExecuteSql
*/
ExecuteSql getInvalidateItems(String uniqueKey); /**
* 计算实际值的SQL语句
* @return ExecuteSql
*/
ExecuteSql getActualValue(String uniqueKey); /**
* 实际值的字段名
*/
default String getActualName() {
return "actual_value";
}
// 实际值的类型,比如数字,百分比或者列表
default String getActualValueType() {
return MetricActualValueType.COUNT.getDescription();
}
// 对参数进行检查并输出检查结果
CheckResult validateConfig(Map<String,Object> config);
//规则所需要的参数
Map<String, ConfigItem> getConfigMap();
//构造规则前需要做的检查
void prepare(Map<String,String> config); default String getIssue() {
return "";
}
// 适合哪些字段类型
List<DataVinesDataType> suitableType();
// 是否支持多选,比如表行数检查支持多张表
default boolean supportMultiple() {
return false;
}
// 对规则参数的重新构造,配合表行数多张表检查
default List<Map<String,Object>> getMetricParameter(Map<String,Object> metricParameter) {
return Collections.singletonList(metricParameter);
}
}

BaseSingleTable 抽象类

BaseSingleTable是实现了 SqlMetric 接口的抽象类,实现了表级别检查规则中所需要参数的添加、错误数据SQL语句构造和实际值计算SQL语句构造和对过滤条件的处理等。

  • 这里定义了获取不符合规则的数据的基础SQL语句,判断类型的规则比如正则表达式检查和枚举值检查,只需要在基础SQL语句后面添加过滤条件即可。
    protected StringBuilder invalidateItemsSql = new StringBuilder("select * from ${table}");
  • 实际值计算SQL语句默认是计算不符合规则数据的行数
String actualValueSql = "select count(1) as actual_value_"+ uniqueKey +" from ${invalidate_items_table}";
  • 计算平均值、汇总值等统计类型的规则需要重新实现getActualValue()中的ExecuteSql
public abstract class BaseSingleTable implements SqlMetric {
// 这里定义了获取不符合规则的数据的基础 SQL 语句,判断类的规则比如正则表达式和枚举值检查,只需要在基础SQL后面添加过滤条件即可。
protected StringBuilder invalidateItemsSql = new StringBuilder("select * from ${table}"); protected List<String> filters = new ArrayList<>(); protected HashMap<String,ConfigItem> configMap = new HashMap<>(); protected Set<String> requiredOptions = new HashSet<>(); public BaseSingleTable() {
configMap.put("table",new ConfigItem("table", "表名", "table"));
configMap.put("filter",new ConfigItem("filter", "过滤条件", "filter")); requiredOptions.add("table");
} @Override
public ExecuteSql getInvalidateItems(String uniqueKey) {
ExecuteSql executeSql = new ExecuteSql();
executeSql.setResultTable("invalidate_items_" + uniqueKey);
executeSql.setSql(invalidateItemsSql.toString());
executeSql.setErrorOutput(isInvalidateItemsCanOutput());
return executeSql;
} @Override
public ExecuteSql getActualValue(String uniqueKey) {
ExecuteSql executeSql = new ExecuteSql();
executeSql.setResultTable("invalidate_count_" + uniqueKey);
String actualValueSql = "select count(1) as actual_value_"+ uniqueKey +" from ${invalidate_items_table}";
executeSql.setSql(actualValueSql);
executeSql.setErrorOutput(false);
return executeSql;
} @Override
public CheckResult validateConfig(Map<String, Object> config) {
return ConfigChecker.checkConfig(config, requiredOptions);
} @Override
public void prepare(Map<String, String> config) {
if (config.containsKey("filter")) {
filters.add(config.get("filter"));
} addFiltersIntoInvalidateItemsSql();
} private void addFiltersIntoInvalidateItemsSql() {
if (filters.size() > 0) {
invalidateItemsSql.append(" where ").append(String.join(" and ", filters));
}
} @Override
public MetricLevel getLevel() {
return MetricLevel.TABLE;
}
}

BaseSingleTableColumn 抽象类

BaseSingleTableColumn是列级别的抽象实现类,主要是添加列级别规则的通用参数。

public abstract class BaseSingleTableColumn extends BaseSingleTable {

    public BaseSingleTableColumn() {
super();
configMap.put("column",new ConfigItem("column", "列名", "column"));
requiredOptions.add("column");
} @Override
public Map<String, ConfigItem> getConfigMap() {
return configMap;
} @Override
public MetricLevel getLevel() {
return MetricLevel.COLUMN;
} @Override
public boolean isInvalidateItemsCanOutput() {
return false;
}
}

第二步

了解完上面的三个基础类以后,自定义一个Metric就变得格外简单了。

基础工作

在 datavines-metric-plugins 下创建一个新规则的 module

在 pom.xml 中添加

 <dependency>
<groupId>io.datavines</groupId>
<artifactId>datavines-metric-base</artifactId>
<version>${project.version}</version>
</dependency>

以 枚举值检查 规则为例来讲解

  • 判断要实现的规则的级别,因为枚举值检查是列级别,所以继承 BaseSingleTableColumn 即可。
  • 在构造函数中的configMap添加enum_list参数用于返回给前端进行展示,在requiredOptions添加enum_list用于参数的检查。
  • 实现英文名、中文名、规则维度、规则类型这些基础的属性。
  • 因为枚举值检查规则是为了找出在枚举值列表中的数据,所以只需要在fileters这个数组里面加入(${column} in ( ${enum_list} ))prepare()方法会自动进行不符合规则的SQL语句构造。
  • 实现suitableType()方法添加规则适用的字段类型。
public class ColumnInEnums extends BaseSingleTableColumn {

    public ColumnInEnums(){
super();
configMap.put("enum_list",new ConfigItem("enum_list", "枚举值列表", "enum_list"));
requiredOptions.add("enum_list");
} @Override
public String getName() {
return "column_in_enums";
} @Override
public String getZhName() {
return "枚举值检查";
} @Override
public MetricDimension getDimension() {
return MetricDimension.EFFECTIVENESS;
} @Override
public MetricType getType() {
return MetricType.SINGLE_TABLE;
} @Override
public boolean isInvalidateItemsCanOutput() {
return true;
} @Override
public void prepare(Map<String, String> config) {
if (config.containsKey("enum_list") && config.containsKey("column")) {
filters.add(" (${column} in ( ${enum_list} )) ");
}
super.prepare(config);
} @Override
public List<DataVinesDataType> suitableType() {
return Arrays.asList(DataVinesDataType.NUMERIC_TYPE, DataVinesDataType.STRING_TYPE, DataVinesDataType.DATE_TIME_TYPE);
}
}

第三步

非常重要的一步

  • 在 resources 目录下创建META-INF/plugins目录。
  • 在 plugins 目录下创建文件并且命名为io.datavines.metric.api.SqlMetric
  • 在文件中添加column_in_enums=io.datavines.metric.plugin.ColumnInEnums

第四步

打包成jar放到 datavines 目录下的libs目录下即可。

收工!自定义 Metric 就这样轻松搞定了。

教程 | Datavines 自定义数据质量检查规则(Metric)的更多相关文章

  1. 基于 DolphinScheduler 的数据质量检查实践

    今天给大家带来的分享是基于 Apache DolphinScheduler 的数据质量检查实践,分享的内容主要为以下四点: " 为什么要做数据质量检查? 为什么要基于 DolphinSche ...

  2. vue教程2-08 自定义键盘信息、监听数据变化vm.$watch

    vue教程2-08 自定义键盘信息 @keydown.up @keydown.enter @keydown.a/b/c.... 自定义键盘信息: Vue.directive('on').keyCode ...

  3. Silverlight实例教程 – Datagrid,Dataform数据验证和ValidationSummary(转载)

    Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...

  4. Windows 8实例教程系列 - 自定义应用风格

    原文:Windows 8实例教程系列 - 自定义应用风格 在Windows 8 XAML实例教程中,曾经提及过应用风格设计方法以及如何创建可复用样式代码.本篇将深入讨论如何创建自定义Windows8应 ...

  5. 数据挖掘实战<1>:数据质量检查

    数据行业有一句很经典的话--"垃圾进,垃圾出"(Garbage in, Garbage out, GIGO),意思就是,如果使用的基础数据有问题,那基于这些数据得到的任何产出都是没 ...

  6. Spring 系列教程之自定义标签的解析

    Spring 系列教程之自定义标签的解析 在之前的章节中,我们提到了在 Spring 中存在默认标签与自定义标签两种,而在上一章节中我们分析了 Spring 中对默认标签的解析过程,相信大家一定已经有 ...

  7. 数据准备<1>:数据质量检查-理论篇

    数据行业有一句很经典的话--"垃圾进,垃圾出"(Garbage in, Garbage out, GIGO),意思就是,如果使用的基础数据有问题,那基于这些数据得到的任何产出都是没 ...

  8. [Pytorch]PyTorch Dataloader自定义数据读取

    整理一下看到的自定义数据读取的方法,较好的有一下三篇文章, 其实自定义的方法就是把现有数据集的train和test分别用 含有图像路径与label的list返回就好了,所以需要根据数据集随机应变. 所 ...

  9. React Native实战系列教程之自定义原生UI组件和VideoView视频播放器开发

    React Native实战系列教程之自定义原生UI组件和VideoView视频播放器开发   2016/09/23 |  React Native技术文章 |  Sky丶清|  4 条评论 |  1 ...

  10. 利用Tensorflow训练自定义数据

    很多正在入门或刚入门TensorFlow机器学习的同学希望能够通过自己指定图片源对模型进行训练,然后识别和分类自己指定的图片.但是,在TensorFlow官方入门教程中,并无明确给出如何把自定义数据输 ...

随机推荐

  1. Design as You See FIT 阅读笔记

    Design as You See FIT 作者及会议名称:DATE 2009, Daniel Holcomb, UC Berkeley 本文的重点贡献:提出了一种新方法计算时序电路发生系统级故障对输 ...

  2. 如何实现 Java SpringBoot 自动验证入参数据的有效性

    Java SpringBoot 通过javax.validation.constraints下的注解,实现入参数据自动验证 如果碰到 @NotEmpty 否则不生效,注意看下 @RequestBody ...

  3. Pytorch实现分类器

    本文实现两个分类器: softmax分类器和感知机分类器 Softmax分类器 Softmax分类是一种常用的多类别分类算法,它可以将输入数据映射到一个概率分布上.Softmax分类首先将输入数据通过 ...

  4. 已知n个数的入栈序列,求一共有多少种出栈序列 (卡特兰数)

    已知\(n\)个数的入栈序列,求一共有多少种出栈序列 这个经典问题有两种解法. 解法一: 设\(f(x)\)为\(x\)个数入栈后,再全部出栈的序列数量 假设我们有\(4\)个数\(a,b,c,d\) ...

  5. 安卓机上 4G 内存跑 alpaca,欢迎试用轻量级 LLM 模型推理框架 InferLLM

    从 LLM 火爆以来,社区已经出现了非常多优秀的模型,当然他们最大的特点就是体积大,最近为了让大模型可以在更低端的设备上运行,社区做了非常多的工作, gptq 实现了将模型进行低比特量化,因此降低了运 ...

  6. Unity2021SteamingAssets数量限制导致打包异常解决

    最近将项目从Unity2019升级到Unity2021,打包安卓的时候出现异常.查了下资料说是数量超出限制,需要设置不压缩的数量. 1. 使用自定义mainTemplate.gradle 打开编辑,a ...

  7. 2022-06-02:一开始在0位置,每一次都可以向左或者向右跳, 第i次能向左或者向右跳严格的i步。 请问从0到x位置,至少跳几次可以到达。 来自字节。 力扣754. 到达终点数字。

    2022-06-02:一开始在0位置,每一次都可以向左或者向右跳, 第i次能向左或者向右跳严格的i步. 请问从0到x位置,至少跳几次可以到达. 来自字节. 力扣754. 到达终点数字. 答案2022- ...

  8. 2022-02-13:k8s安装gitlab,yaml如何写?

    2022-02-13:k8s安装gitlab,yaml如何写? 答案2022-02-13: yaml如下: apiVersion: apps/v1 kind: Deployment metadata: ...

  9. Winform 遮罩懒人处理法

    前言 之前有个项目需要执行一个略微耗时的操作大概五六七八九十秒这样子,这个时候程序不能做其他操作,只能等待操作完成.为了提升一丝使用体验同时让Winform程序看上去高级一点,就想到加一个遮罩层(Ma ...

  10. wmi搜集一台计算机的硬件信息

    作用: Python搜集一台计算机的硬件信息,借助模块:wmi,这个模块只支持window操作系统. 安装: pip install wmi 导入: import wmi 实例 c = wmi.WMI ...