datahub使用-字段级&表级数据血缘-clickhouse

参考两位大佬的文章综合了一下

Datahub实践——Sqllineage解析Sql实现端到端数据血缘_实时计算的技术博客_51CTO博客

sqllineage解析sql列级血缘并提交到datahub-CSDN博客

目录

元数据摄取-clickhouse

数据血缘自动识别及上传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生成),如下

 

  • 12
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
根据你提供的代码,我可以解释一下其中的宏定义的含义: 1. `prev_inuse(p)`:该宏用于判断前一个相邻的内存块是否被使用。通过与 `PREV_INUSE` 进行按位与运算,可以获取到 size 字段中的对应位。如果结果为非零值,则表示前一个内存块被使用,否则未使用。 2. `chunk_is_mmapped(p)`:该宏用于判断当前内存块是否是通过 `mmap()` 函数从操作系统中获取的。通过与 `IS_MMAPPED` 进行按位与运算,可以获取到 size 字段中的对应位。如果结果为非零值,则表示当前内存块是通过 `mmap()` 获取的,否则不是。 3. `chunk_non_main_arena(p)`:该宏用于判断当前内存块是否来自于非主要的堆空间(arena)。通过与 `NON_MAIN_ARENA` 进行按位与运算,可以获取到 size 字段中的对应位。如果结果为非零值,则表示当前内存块来自于非主要的堆空间,否则来自于主要的堆空间。 4. `inuse(p)`:该宏用于判断当前内存块是否被使用。它通过将 size 字段与 `SIZE_BITS` 进行按位与运算,获取到当前内存块的大小,并返回前一个相邻内存块的 inuse 位。 5. `set_inuse(p)`:该宏用于将当前内存块的 inuse 位设置为 1。它通过将 size 字段与 `SIZE_BITS` 进行按位与运算,然后设置前一个相邻内存块的 size 字段的 inuse 位为 1。 6. `clear_inuse(p)`:该宏用于将当前内存块的 inuse 位清除(置为 0)。它通过将 size 字段与 `SIZE_BITS` 进行按位与运算,然后将前一个相邻内存块的 size 字段的 inuse 位清除。 这些宏定义用于在堆管理中对内存块的元数据进行操作和判断,以支持堆的正确分配和释放操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值