参考两位大佬的文章综合了一下
Datahub实践——Sqllineage解析Sql实现端到端数据血缘_实时计算的技术博客_51CTO博客
sqllineage解析sql列级血缘并提交到datahub-优快云博客
目录
元数据摄取-clickhouse
自动获取clickhouse数据字典形成元数据信息
datahub前端下列界面设置clickhouse数据源
配置信息
source:
type: clickhouse
config:
host_port: '10:XXX.XXX.XXX:8123'#clickhouse 地址
username: user
password: pw
include_views: true
include_tables: true
sink:
type: datahub-rest
config:
server: 'http://datahub-source:8080'#datahub地址
执行成功后可从前台查看是否获取成功
点击platforms查看获取clickhouse结果
数据血缘自动识别及上传datahub
通过sqllineage获取指定sql文件中HiveSQL的字段级血缘关系,并将结果提交到datahub
参考datahub官方文档给出的提交细粒度血缘的脚本datahub/lineage_emitter_dataset_finegrained.py at master · datahub-project/datahub · GitHub
参考sqllineage文档Getting Started — sqllineage 1.3.7 documentation
结合sqllineage,获取指定sql的列级血缘,再调用datahub rest api,将结果提交到datahub
具体py代码如下
from sqllineage.runner import LineageRunner
import datahub.emitter.mce_builder as builder
from datahub.emitter.mcp import MetadataChangeProposalWrapper
from datahub.emitter.rest_emitter import DatahubRestEmitter
from datahub.metadata.com.linkedin.pegasus2avro.dataset import (
DatasetLineageType,
FineGrainedLineage,
FineGrainedLineageDownstreamType,
FineGrainedLineageUpstreamType,
Upstream,
UpstreamLineage,
)
import sys
'''
解析目标sql文件的HiveSQL生成列级血缘,提交到datahub
sql文件路径作为命令行参数传入脚本
提交到datahub的platform = clickhouse
'''
# 库名设置
def datasetUrn(tableName):
return builder.make_dataset_urn("Clickhouse", tableName) # platform = clickhouse
# 表、列级信息设置
def fieldUrn(tableName, fieldName):
return builder.make_schema_field_urn(datasetUrn(tableName), fieldName)
# 目标sql文件路径
sqlFilePath = sys.argv[1]
sqlFile = open(sqlFilePath, mode='r', encoding='utf-8')
sql = sqlFile.read().__str__()
# 获取sql血缘
result = LineageRunner(sql)
# 获取sql中的下游表名
targetTableName = result.target_tables[0].__str__()
print(result)
print('===============')
# 打印列级血缘结果
result.print_column_lineage()
print('===============')
# 获取列级血缘
lineage = result.get_column_lineage
# 字段级血缘list
fineGrainedLineageList = []
# 用于冲突检查的上游list
upStreamsList = []
# 遍历列级血缘
for columnTuples in lineage():
# 上游list
upStreamStrList = []
# 下游list
downStreamStrList = []
# 逐个字段遍历
for column in columnTuples:
# 元组中最后一个元素为下游表名与字段名,其他元素为上游表名与字段名
# 遍历到最后一个元素,为下游表名与字段名
if columnTuples.index(column) == len(columnTuples) - 1:
downStreamFieldName = column.raw_name.__str__()
downStreamTableName = column.__str__().replace('.' + downStreamFieldName, '').__str__()
# print('下游表名:' + downStreamTableName)
# print('下游字段名:' + downStreamFieldName)
downStreamStrList.append(fieldUrn(downStreamTableName, downStreamFieldName))
else:
upStreamFieldName = column.raw_name.__str__()
upStreamTableName = column.__str__().replace('.' + upStreamFieldName, '').__str__()
# print('上游表名:' + upStreamTableName)
# print('上游字段名:' + upStreamFieldName)
upStreamStrList.append(fieldUrn(upStreamTableName, upStreamFieldName))
# 用于检查上游血缘是否冲突
upStreamsList.append(Upstream(dataset=datasetUrn(upStreamTableName), type=DatasetLineageType.TRANSFORMED))
fineGrainedLineage = FineGrainedLineage(upstreamType=FineGrainedLineageUpstreamType.DATASET,
upstreams=upStreamStrList,
downstreamType=FineGrainedLineageDownstreamType.FIELD_SET,
downstreams=downStreamStrList)
fineGrainedLineageList.append(fineGrainedLineage)
fieldLineages = UpstreamLineage(
upstreams=upStreamsList, fineGrainedLineages=fineGrainedLineageList
)
lineageMcp = MetadataChangeProposalWrapper(
entityUrn=datasetUrn(targetTableName), # 下游表名
aspect=fieldLineages
)
# 调用datahub REST API
emitter = DatahubRestEmitter('http://10.XXX.XXX.XXX.XXX:8080') # datahub server
# Emit metadata!
emitter.emit_mcp(lineageMcp)
#将表之间血缘关系进一步上传,弥补字段级血缘关系解析来源表少一部分的问题
for target_table in result.target_tables:
target_table=str(target_table)
print(target_table)
input_tables_urn = []
for source_table in result.source_tables:
source_table=str(source_table)
input_tables_urn.append(builder.make_dataset_urn("clickhouse", source_table))
print(input_tables_urn)
lineage_mce = builder.make_lineage_mce(
input_tables_urn,
builder.make_dataset_urn("clickhouse", target_table),
)
emitter.emit_mce(lineage_mce)
try:
emitter.emit_mce(lineage_mce)
print("添加数仓表 【{}】血缘成功".format(target_table))
except Exception as e:
print("添加数仓表 【{}】血缘失败".format(target_table))
print(e)
break
将上述py文件及sql文件一并上传至datahub服务器,执行一下命令
python sql-lineage-to-datahub.py target_table.sql
查看目标表血缘关系
同理,可上传与目标表下游表相关sql文件,并执行,可串联起所有与该表相关的数据血缘(下图是上传了5个sql生成),如下