如何将SQLFlow工具产生的血缘导入到Datahub平台中

介绍

马哈鱼数据血缘分析工具(英文名称为 Gudu SQLFlow )是一款用于分析 SQL 语句,并发现其中数据血缘关系的分析软件,经常和元数据管理工具一起使用,是企业数据治理的基础工具。

而Datahub是一款‌流式数据处理平台,核心功能是实时收集、存储、处理和分发数据,支持构建实时分析和应用‌,并且也支持进行数据血缘分析。

本篇文章主要介绍如何将SQLFlow工具产生的血缘导入到Datahub平台中。

一个示例 SQL 语句

我们利用下面这个稍微有点复杂的 SQL 语句来演示如何利用 Gudu SQLFlow 快速获取各种数据血缘关系,如果你有更复杂的 SQL 语句或者存储过程 (stored procedure) 需要处理,那么更需要一个像 Gudu SQLFlow 这样的数据血缘分析工具。

sql 复制代码
select data.*, location.remote
from (
	select e.last_name, e.department_id, d.department_name
	from employees e
	left outer join department d
		on (e.department_id = d.department_id)
) data inner join
(
	select s.remote,s.department_id 
	from source s
	inner join location l 
	on s.location_id = l.id
) location on data.department_id = location.department_id;

该 SQL 包含两个子查询:

子查询 1:data

来源表:

  • employees
  • department

输出字段:

  • last_name
  • department_id
  • department_name

连接方式:

sql 复制代码
employees LEFT JOIN department
ON employees.department_id = department.department_id

子查询 2:location

来源表:

  • source
  • location

输出字段:

  • remote
  • department_id

连接方式:

sql 复制代码
source INNER JOIN location
ON source.location_id = location.id

最终查询

最终输出表(图中为 RS-1)来源于:

sql 复制代码
data INNER JOIN location
ON data.department_id = location.department_id

最终字段:

  • last_name
  • department_id
  • department_name
  • remote

使用SQLFlow分析血缘

我们的目标是需要知道顶层的 select list 中包含哪些字段(column),并且这些字段的源数据来自其它哪些表和字段。SQLFLow分析的血缘结果如图:

表级血缘关系

从图中可以看出,最终结果表 RS-1 的上游来源共有四张表:

  • employees
  • department
  • source
  • location

血缘路径如下:

复制代码
employees ──┐
             ├── RESULT_OF_DATA-1 ──┐
department ─┘                       │
                                     ├── RS-1
source ─────┐                        │
             ├── RESULT_OF_LOCATION-1┘
location ────┘

说明:

  • employees 和 department 共同生成中间结果 RESULT_OF_DATA-1
  • source 和 location 共同生成中间结果 RESULT_OF_LOCATION-1
  • 两个中间结果通过 department_id 再次关联,生成最终表 RS-1

字段级血缘关系

根据血缘图,可以明确每个字段的来源。

1️⃣ last_name

来源路径:

复制代码
employees.last_name → RESULT_OF_DATA-1.last_name → RS-1.last_name

最终字段来源于 employees 表。

2️⃣ department_id

该字段有两条来源路径:

复制代码
employees.department_id
source.department_id

血缘关系:

复制代码
employees.department_id → RESULT_OF_DATA-1.department_id
source.department_id → RESULT_OF_LOCATION-1.department_id

最终在 RS-1 中作为 join 条件字段存在。

3️⃣ department_name

来源路径:

复制代码
department.department_name → RESULT_OF_DATA-1.department_name → RS-1.department_name

最终来源于 department 表。

4️⃣ remote

来源路径:

复制代码
source.remote → RESULT_OF_LOCATION-1.remote → RS-1.remote

最终来源于 source 表。

血缘特征总结

该 SQL 的血缘特点:

  • 存在两个独立子查询
  • 每个子查询内部有 Join
  • 子查询结果再次 Join
  • 存在字段透传(data.*)
  • 存在跨层级字段传递

血缘图完整体现了:

  • 表级依赖关系
  • 字段级来源路径
  • 多层 Join 结构
  • 中间结果节点

将SQLFLow血缘导入Datahub

  1. 先将SQLFLow的血缘导出到本地:

    导出后的文件例如:oracle_1771415869013.json

  2. 使用下面的脚本导入血缘:

py 复制代码
import json
import sys

from datahub.emitter.rest_emitter import DatahubRestEmitter
from datahub.metadata.schema_classes import (
    UpstreamLineageClass,
    UpstreamClass,
    DatasetPropertiesClass,
    ChangeTypeClass,
)
from datahub.emitter.mcp import MetadataChangeProposalWrapper

emitter = DatahubRestEmitter("http://localhost:8080")


def build_dataset_urn(table_name):
    table_name = table_name.lower()
    return f"urn:li:dataset:(urn:li:dataPlatform:oracle,{table_name},PROD)"


def main(file_path):
    with open(file_path, "r") as f:
        data = json.load(f)

    relationships = data["data"]["sqlflow"]["relationships"]

    created_tables = set()

    for rel in relationships:
        target_table = rel["target"]["parentName"]

        for src in rel["sources"]:
            source_table = src["parentName"]

            source_urn = build_dataset_urn(source_table)
            target_urn = build_dataset_urn(target_table)

            # 1️⃣ 创建 source dataset(避免页面不显示)
            if source_table not in created_tables:
                mcp_source = MetadataChangeProposalWrapper(
                    entityUrn=source_urn,
                    entityType="dataset",
                    aspect=DatasetPropertiesClass(
                        description="Imported from sqlflow"
                    ),
                    aspectName="datasetProperties",
                    changeType=ChangeTypeClass.UPSERT,
                )
                emitter.emit(mcp_source)
                created_tables.add(source_table)

            # 2️⃣ 创建 target dataset
            if target_table not in created_tables:
                mcp_target = MetadataChangeProposalWrapper(
                    entityUrn=target_urn,
                    entityType="dataset",
                    aspect=DatasetPropertiesClass(
                        description="Imported from sqlflow"
                    ),
                    aspectName="datasetProperties",
                    changeType=ChangeTypeClass.UPSERT,
                )
                emitter.emit(mcp_target)
                created_tables.add(target_table)

            # 3️⃣ 建立血缘(source -> target)
            lineage = UpstreamLineageClass(
                upstreams=[
                    UpstreamClass(
                        dataset=source_urn,
                        type="TRANSFORMED",
                    )
                ]
            )

            mcp_lineage = MetadataChangeProposalWrapper(
                entityUrn=target_urn,
                entityType="dataset",
                aspect=lineage,
                aspectName="upstreamLineage",
                changeType=ChangeTypeClass.UPSERT,
            )

            emitter.emit(mcp_lineage)

    print("Lineage uploaded successfully!")


if __name__ == "__main__":
    main(sys.argv[1])

执行命令:

sh 复制代码
python convert.py oracle_1771415869013.json

导入成功后,在datahub页面中可以看到如下的结果:

其中,例如 department 字段的表级别血缘结果如下:

和SQLFlow的表级别血缘一致:

总结我们可以在SQLFlow中分析详细的到字段级别的血缘,也可以将SQLFlow分析的结果导入到Datahub中查看表级别的血缘。

参考

马哈鱼数据血缘关系分析工具中文网站: https://www.sqlflow.cn

马哈鱼数据血缘关系分析工具英文网站: https://docs.gudusoft.com

马哈鱼数据血缘关系分析工具在线使用: https://sqlflow.gudusoft.com

相关推荐
用户8307196840823 小时前
Spring Boot WebClient性能比RestTemplate高?看完秒懂!
java·spring boot
IvorySQL3 小时前
PostgreSQL 技术日报 (3月11日)|4库合一性能提升350倍与内核新讨论
数据库·postgresql·开源
IvorySQL3 小时前
谁动了我的查询结果?PostgreSQL 联表加锁的隐藏陷阱
数据库·postgresql·开源
Assby5 小时前
从洋葱模型看Java与Go的设计哲学:为什么它们如此不同?
java·后端·架构
爱可生开源社区6 小时前
🧪 你的大模型实验室开张啦!亲手测出最懂你 SQL 的 AI
数据库·sql·llm
belhomme6 小时前
(面试题)Netty 线程模型
java·面试·netty
赵渝强老师9 小时前
【赵渝强老师】使用TiSpark在Spark中访问TiDB
数据库·mysql·tidb·国产数据库
NE_STOP10 小时前
MyBatis-plus进阶之映射与条件构造器
java
Qinana11 小时前
第一次用向量数据库!手搓《天龙八部》RAG助手,让AI真正“懂”你
前端·数据库·后端