
DataHub Domains API 实战指南通过 GraphQL 与 Python SDK 管理数据域【免费下载链接】datahubThe Context Platform for your Data and AI Stack项目地址: https://gitcode.com/GitHub_Trending/da/datahub本文是 DataHub Domains数据域功能的 API 实战教程完整讲解如何通过 GraphQL API、Curl 命令与 Python SDK 三种方式创建域、创建嵌套域、读取/添加/移除数据集与域的关联关系并结合仓库源码剖析 Domain 的元数据模型与底层执行原理帮助你在 DataHub 中以编程方式落地数据治理中的域Domain分类体系。Domains 是什么为什么需要它Domains 是 DataHub 中的一种元数据实体用于把相关的数据资产显式分组为经过策划curated的顶层文件夹或类别。你可以把 Domain 理解为业务单元或团队维度的一级目录例如Marketing市场部、Finance财务部、Platform Engineering平台工程等。Domain 的管理既可以集中进行也可以下放distributed给 Domain 的负责人Domain owners。关于 Domains 的核心约束与能力一个资产同时只能属于一个 Domain数据集、仪表盘等资产同一时刻只归属一个域这与可以打多个 Tag 的标签体系有本质区别支持嵌套结构Domain 之下可以再建子域Nested Domain形成层级化的分类树支持集中式与分布式治理可通过平台级 privilege 与 Metadata Policy 控制谁有权限建域、谁可以给资产分配域。关于 Domains 与容器的使用边界Domains 更适用于策划与组织。若将其作为基于视图view的访问控制主边界可能会影响性能相关说明见 docs/authorization/policies.md 中的 Domains and containers 一节。本教程目标本教程将带领你完成四个核心操作创建一个 Domain读取数据集dataset当前关联的 Domain将数据集添加到某个 Domain移除数据集上的 Domain。前置条件在开始之前你需要先部署 DataHub Quickstart 并摄入示例数据具体步骤参考 DataHub Quickstart Guide。同时通过 API 创建/修改 Domain 需要具备相应的权限在实体层面添加 Domain 需要Manage Domains平台权限platform privilege为资产添加或移除 Domain 需要Edit Domain元数据权限Metadata Privilege这些权限可以通过创建 Metadata Policy 来授予。若使用 Python SDK还需要确保环境中已安装acryl-datahub相关依赖并可通过环境变量或参数配置 GMS 地址与访问令牌。创建 Domain创建 Domain 的本质是向 DataHub GMSGeneral Metadata Service写入一个带有DomainProperties方面的 Domain 实体。下面分别给出 GraphQL、Curl、Python SDK 三种实现方式。方式一GraphQL Mutationmutation createDomain { createDomain(input: { name: Marketing, description: Entities related to the marketing department }) }如果操作成功将返回新创建 Domain 的 URN{ data: { createDomain: domain_urn }, extensions: {} }方式二Curl 调用 GraphQL 端点curl --location --request POST http://localhost:8080/api/graphql \ --header Authorization: Bearer my-access-token \ --header Content-Type: application/json \ --data-raw { query: mutation createDomain { createDomain(input: { name: \Marketing\, description: \Entities related to the marketing department.\ }) }, variables:{}}预期响应{ data: { createDomain: domain_urn }, extensions: {} }方式三Python SDK使用acryl-datahub的 REST Emitter 与 MCPMetadataChangeProposal机制创建 Domain。完整可运行示例见 metadata-ingestion/examples/library/domain_create.pyimport os from datahub.emitter.mce_builder import make_domain_urn from datahub.emitter.mcp import MetadataChangeProposalWrapper from datahub.emitter.rest_emitter import DatahubRestEmitter from datahub.metadata.schema_classes import DomainPropertiesClass # Get DataHub connection details from environment gms_server os.getenv(DATAHUB_GMS_URL, http://localhost:8080) token os.getenv(DATAHUB_GMS_TOKEN) domain_urn make_domain_urn(marketing) domain_properties_aspect DomainPropertiesClass( nameMarketing, descriptionEntities related to the marketing department ) event: MetadataChangeProposalWrapper MetadataChangeProposalWrapper( entityUrndomain_urn, aspectdomain_properties_aspect, ) rest_emitter DatahubRestEmitter(gms_servergms_server, tokentoken) rest_emitter.emit(event) print(fCreated domain {domain_urn})关键点解读make_domain_urn(marketing)会把裸名称规范化为urn:li:domain:marketing见 mce_builder.py 的实现若传入值已以urn:li:domain:开头则原样返回DomainPropertiesClass对应 Domain 的domainProperties方面包含name与可选的description字段DatahubRestEmitter默认指向http://localhost:8080可通过环境变量DATAHUB_GMS_URL与DATAHUB_GMS_TOKEN覆盖。创建 Domain 的预期结果创建成功后登录 DataHub UI进入Govern Domains页面即可看到新建的Marketing域。创建嵌套 DomainNested DomainDomain 支持层级结构——可以在某个已存在的 Domain 下创建子域只需在createDomain的输入参数中传入parentDomain。GraphQL 方式mutation createDomain { createDomain(input: { name: Verticals, description: An optional description, parentDomain: urn:li:domain:marketing }) }Curl 方式curl --location --request POST http://localhost:8080/api/graphql \ --header Authorization: Bearer my-access-token \ --header Content-Type: application/json \ --data-raw { query: mutation createDomain { createDomain(input: { name: \Verticals\, description: \Entities related to the verticals sub-domain.\, parentDomain: \urn:li:domain:marketing\ }) }, variables:{}}Python 方式完整示例见 metadata-ingestion/examples/library/domain_create_nested.pyimport os from datahub.emitter.mce_builder import make_domain_urn from datahub.emitter.mcp import MetadataChangeProposalWrapper from datahub.emitter.rest_emitter import DatahubRestEmitter from datahub.metadata.schema_classes import DomainPropertiesClass domain_urn make_domain_urn(verticals) domain_properties_aspect DomainPropertiesClass( nameVerticals, descriptionEntities related to the verticals sub-domain, parentDomainurn:li:domain:marketing, ) event: MetadataChangeProposalWrapper MetadataChangeProposalWrapper( entityUrndomain_urn, aspectdomain_properties_aspect, ) # Get DataHub connection details from environment gms_server os.getenv(DATAHUB_GMS_URL, http://localhost:8080) token os.getenv(DATAHUB_GMS_TOKEN) rest_emitter DatahubRestEmitter(gms_servergms_server, tokentoken) rest_emitter.emit(event) print(fCreated domain {domain_urn})这条查询会在Marketing域下创建名为Verticals的新子域。从元数据模型看嵌套关系正是通过DomainProperties方面中的parentDomain: optional Urn字段表达见 DomainProperties.pdl。读取数据集的 Domain创建好 Domain 并把资产关联进去之后你可以随时查询某个数据集当前所属的 Domain。GraphQL 查询query { dataset(urn: urn:li:dataset:(urn:li:dataPlatform:hive,fct_users_created,PROD)) { domain { associatedUrn domain { urn properties { name } } } } }预期响应domain.associatedUrn是被关联资产自身的 URNdomain则是它所属的 Domain 实体{ data: { dataset: { domain: { associatedUrn: urn:li:dataset:(urn:li:dataPlatform:hive,fct_users_created,PROD), domain: { urn: urn:li:domain:71b3bf7b-2e3f-4686-bfe1-93172c8c4e10, properties: { name: Marketing } } } } }, extensions: {} }Curl 查询curl --location --request POST http://localhost:8080/api/graphql \ --header Authorization: Bearer my-access-token \ --header Content-Type: application/json \ --data-raw { query: { dataset(urn: \urn:li:dataset:(urn:li:dataPlatform:hive,fct_users_created,PROD)\) { domain { associatedUrn domain { urn properties { name } } } } }, variables:{}}预期响应与 GraphQL 方式相同。Python SDK 读取高层的datahub.sdk客户端提供了更简洁的读取方式完整示例见 metadata-ingestion/examples/library/dataset_query_domain.pyfrom datahub.sdk import DataHubClient, DatasetUrn client DataHubClient.from_env() dataset client.entities.get( DatasetUrn(platformhive, namefct_users_created, envPROD) ) # Print the dataset domain print(dataset.domain)这里DataHubClient.from_env()会从环境变量读取 GMS 地址与凭证配置DatasetUrn则用结构化参数platform / name / env替代手写冗长的 URN 字符串。为数据集添加 Domain将一个数据集归属到某个 Domain 使用setDomainmutation。注意该操作会覆盖数据集上已有的 Domain 归属一个资产同一时刻只能属于一个 Domain。GraphQL Mutationmutation setDomain { setDomain(domainUrn: urn:li:domain:marketing, entityUrn: urn:li:dataset:(urn:li:dataPlatform:hive,fct_users_created,PROD)) }预期响应{ data: { setDomain: true }, extensions: {} }Curl 调用curl --location --request POST http://localhost:8080/api/graphql \ --header Authorization: Bearer my-access-token \ --header Content-Type: application/json \ --data-raw { query: mutation setDomain { setDomain(entityUrn: urn:li:dataset:(urn:li:dataPlatform:hive,fct_users_created,PROD), domainUrn: urn:li:domain:marketing)) }, variables:{}}预期响应{ data: { setDomain: true }, extensions: {} }Python SDK 添加使用 SDK 的实体更新接口完成读-改-写read-modify-write完整示例见 metadata-ingestion/examples/library/dataset_add_domain.pyfrom datahub.metadata.urns import DatasetUrn, DomainUrn from datahub.sdk import DataHubClient client DataHubClient.from_env() dataset client.entities.get(DatasetUrn(platformsnowflake, nameexample_dataset)) # If you dont know the domain urn, you can look it up: # domain_urn client.resolve.domain(namemarketing) # NOTE: This will overwrite the existing domain dataset.set_domain(DomainUrn(idmarketing)) client.entities.update(dataset)要点说明DomainUrn(idmarketing)会构造出urn:li:domain:marketing注释中给出的client.resolve.domain(namemarketing)是在不知道 Domain URN 时按名称解析的辅助方式代码注释明确提示set_domain会覆盖该数据集已有的 Domain。添加 Domain 的预期结果操作完成后进入数据集的详情页即可看到Marketing域已被添加到该数据集。移除数据集的 Domain当资产不再属于某个域或需要清空其归属时使用unsetDomainmutation。GraphQL Mutationmutation unsetDomain { unsetDomain( entityUrn:urn:li:dataset:(urn:li:dataPlatform:hive,fct_users_created,PROD) ) }预期响应{ data: { removeDomain: true }, extensions: {} }Curl 调用curl --location --request POST http://localhost:8080/api/graphql \ --header Authorization: Bearer my-access-token \ --header Content-Type: application/json \ --data-raw { query: mutation unsetDomain { unsetDomain(entityUrn: \urn:li:dataset:(urn:li:dataPlatform:hive,fct_users_created,PROD)\) }, variables:{}}Python 通过 DataHubGraph 执行 GraphQL与创建 Domain使用 RestEmitter 不同移除 Domain这一操作需要基于图graph的读写能力因此示例改用DataHubGraph直接执行 GraphQL mutation完整示例见 metadata-ingestion/examples/library/dataset_remove_domain_execute_graphql.py# read-modify-write requires access to the DataHubGraph (RestEmitter is not enough) from datahub.ingestion.graph.client import DatahubClientConfig, DataHubGraph gms_endpoint http://localhost:8080 graph DataHubGraph(DatahubClientConfig(servergms_endpoint)) # Query multiple aspects from entity query mutation unsetDomain { unsetDomain( entityUrn:urn:li:dataset:(urn:li:dataPlatform:hive,fct_users_created,PROD) ) } result graph.execute_graphql(queryquery) print(result)移除 Domain 的预期结果操作成功后fct_users_created数据集上将不再显示Marketing域标签。源码视角Domain 的底层实现原理为了让上文中的操作更可信、可排查这里从仓库源码补充 Domain 的落地机制。GraphQL Resolver 层Domain 相关的全部 GraphQL Resolver 位于 datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/domain/ 目录CreateDomainResolver.java处理createDomainmutation接收name、description、parentDomain输入并写入新 Domain 实体SetDomainResolver.java处理setDomainmutation将实体与 Domain 建立关联UnsetDomainResolver.java处理unsetDomainmutation解除实体与 Domain 的关联ListDomainsResolver.java处理listDomains查询DomainEntitiesResolver.java返回某 Domain 下的实体列表ParentDomainsResolver.java支撑嵌套域的父域解析DeleteDomainResolver.java删除 Domain。另外 DomainAssociationMapper.java 负责把底层的 Domain 关联数据映射为 GraphQL 响应中的domain { associatedUrn ... }结构这正是本文读取数据集的 Domain一节中响应字段的来源。元数据模型层Domain 的模型定义在 metadata-models/src/main/pegasus/com/linkedin/domain/DomainProperties.pdl定义domainProperties方面核心字段为name: string、description: optional string、parentDomain: optional Urn嵌套域的支撑字段Domains.pdl定义domains方面承载实体与 Domain 的关联AssociatedWith 关系DomainAssociation.pdl定义 Domain 关联对象的数据结构。URN 构造工具Python 侧统一通过 mce_builder.py 中的 make_domain_urn 生成 Domain URN其逻辑为若输入已带urn:li:domain:前缀则原样返回否则自动补齐前缀。该工具被 ingestion 源如 glue、dynamodb、iceberg、kafka、snowflake 等以及 DataHub API 实体层广泛复用保证了整个项目中 Domain URN 格式的一致性。延伸在 Ingestion 过程中分配 Domain除了通过 API/UI 手动管理DataHub 还支持在数据摄入阶段直接为资产分配 Domain。所有基于 SQL 的 ingestion source如 Snowflake都支持在 recipe 的 source config 中配置domain字段。以下为 Snowflake recipe 示例见 docs/domains.md将long_tail_companions库analyticsschema 下的所有表归入Analytics域将ecommerceschema 下的所有表归入Finance域source: type: snowflake config: username: ${SNOW_USER} password: ${SNOW_PASS} account_id: warehouse: COMPUTE_WH role: accountadmin database_pattern: allow: - long_tail_companions schema_pattern: deny: - information_schema profiling: enabled: False domain: Analytics: allow: - long_tail_companions.analytics.* Finance: allow: - long_tail_companions.ecommerce.*规则细节使用裸域名如Analytics时ingestion 系统会先尝试匹配urn:li:domain:Analytics若不存在则按名称查找已创建的域若都无法解析ingestion 会拒绝继续执行直到该域在 DataHub 上预先创建也可以直接使用完整 URN 避免解析例如domain: urn:li:domain:6289fccc-4af2-4cbb-96ed-051e7d1de93c: allow: - long_tail_companions.analytics.* urn:li:domain:07155b15-cee6-4fda-b1c1-5a19a6b74c3a: allow: - long_tail_companions.ecommerce.*注意Ingestion 时的 Domain 分配会覆盖你在 UI 中手动指定的 Domain因为一张表同一时刻只能归属一个域。常见问题Domains、Tags 与 Glossary Terms 的区别DataHub 将 Tags、Glossary Terms 与 Domains 视为三种用途不同的元数据类型类型定位管理方式数量约束Tags非正式的、松散控制的标签服务于搜索与发现无正式的集中管理一个资产可有多个 TagGlossary Terms受控词表可选层级结构常用于规范 schema 字段级属性如 EMAIL_PLAINTEXT的治理集中维护的词表字段/资产可关联多个术语Domains顶层业务类别集合通常对齐业务单元或学科可集中或分布交由 Domain owner管理一个数据资产同一时刻只能归属一个 Domain更多资源Domain 概念与 UI 操作完整说明覆盖 UI 创建、自定义 Domain id、搜索、按域过滤与首页热门域展示GraphQL API 参考domain/listDomains/createDomain/setDomain/unsetDomain详见 docs/api/graphql想快速试跑示例查询可访问部署环境的your-datahub-url/api/graphiql交互式 GraphQL 控制台。【免费下载链接】datahubThe Context Platform for your Data and AI Stack项目地址: https://gitcode.com/GitHub_Trending/da/datahub创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考