十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

DataHub Semantic Models 实战:用 Python SDK 构建语义模型、逻辑数据集与指标血缘

DataHub Semantic Models 实战:用 Python SDK 构建语义模型、逻辑数据集与指标血缘 DataHub Semantic Models 实战用 Python SDK 构建语义模型、逻辑数据集与指标血缘【免费下载链接】datahubThe Context Platform for your Data and AI Stack项目地址: https://gitcode.com/GitHub_Trending/da/datahub本文基于 DataHub 官方教程docs/api/tutorials/semantic-models.md讲解如何使用 Python SDK v2datahub.sdk在 DataHub 中发出 Semantic Model语义模型、逻辑 Dataset语义模型数据集和 Metric指标实体如何搭建Metric → Logical Dataset → Physical Dataset的完整血缘链、SDK 替你生成了哪些 aspect、如何校验输出的 MCP 形状以及如何通过预检助手规避服务端版本不兼容问题。读完后你可以直接复制示例代码向任意支持 semantic-model 元数据模型的服务端发出语义层元数据。为什么要用 Semantic Models 与 MetricsSemantic Models 和 Metrics 让你在物理数据之上描述一个逻辑层一个semanticModel实体将多个逻辑dataset每个都是 Semantic Model Dataset 子类型分组在一起通过锚定在 schema field 上的semanticFieldAnnotation暴露维度dimensions和度量measures它作为metric实体的底层模型backing model。血缘流向为Metric → Logical Dataset → Physical DatasetSemanticModel 是其成员的容器不是血缘跳从而为分析、治理和 AI 辅助探索提供一个稳定的、与数据源无关的表面。这套建模方式最初存在于 Snowflake 连接器内部被提升到高层 SDK 之后任何生产者连接器或直接使用 SDK 的用户都可以发出同样的实体而无需重新实现 aspect 装配逻辑。本指南的目标构建一个包含两个逻辑数据集、schema 字段和一条 relationship 的SemanticModel发出由该模型支撑的metric实体其中包含一个从另一个指标派生derived的指标将每个发出的 MCP 序列化到文件检查最终的 aspect 形状。前置条件本教程需要安装 DataHub SDK v2datahub.sdk.*。如果你是通过metadata-ingestion包运行示例虚拟环境可通过./gradlew :metadata-ingestion:installDev配置好。构建 Semantic Model、逻辑数据集与指标下面的示例使用高层datahub.sdkbuilder 构建完整的血缘链Metric - Logical Dataset - Physical DatasetSemanticModel 作为其 datasets 与 metrics 的容器然后把每个发出的 MCP 写入 JSON 文件以便检查 aspect 形状。完整可运行版本见 示例脚本运行方式为python -m examples.library.semantic_model_createEmit a semantic model with two logical datasets and two metrics. Run with: python -m examples.library.semantic_model_create import json from typing import Any, List from datahub.emitter.mce_builder import make_dataset_urn from datahub.emitter.mcp import MetadataChangeProposalWrapper from datahub.metadata.schema_classes import ( DialectClass, ERModelRelationshipCardinalityClass, SemanticFieldTypeClass, ) from datahub.metadata.urns import SemanticModelUrn from datahub.sdk import ( AiContextInput, DialectExpressionInput, Metric, SemanticFieldInput, SemanticModel, SemanticModelDataset, SemanticModelRelationshipInput, ) from datahub.sdk.entity import Entity def build_graph() - tuple[SemanticModel, List[Entity]]: platform snowflake model_urn SemanticModelUrn(platformplatform, pathanalytics, idorders_model) orders_ds SemanticModelDataset( platformplatform, nameanalytics.orders_model.orders_ds, semantic_modelmodel_urn, aliasORDERS, schema[ SemanticFieldInput( field_pathorder_id, typeint, semantic_typeSemanticFieldTypeClass.DIMENSION, is_part_of_keyTrue, ), # Foreign key the ORDERS - CUSTOMERS relationship joins on. SemanticFieldInput( field_pathcustomer_id, typeint, semantic_typeSemanticFieldTypeClass.DIMENSION, ), SemanticFieldInput( field_pathorder_ts, typetimestamp, semantic_typeSemanticFieldTypeClass.DIMENSION, is_time_dimensionTrue, ), SemanticFieldInput( field_pathamount, typefloat, semantic_typeSemanticFieldTypeClass.MEASURE, expressionDialectExpressionInput( expressionSUM(amount), dialectDialectClass.SNOWFLAKE ), aggregation_functionSUM, ai_contextAiContextInput(synonyms[revenue]), ), ], upstreams[make_dataset_urn(platform, raw.orders)], ) customers_ds SemanticModelDataset( platformplatform, nameanalytics.orders_model.customers_ds, semantic_modelmodel_urn, aliasCUSTOMERS, schema[ SemanticFieldInput( field_pathcustomer_id, typeint, semantic_typeSemanticFieldTypeClass.DIMENSION, is_part_of_keyTrue, ), SemanticFieldInput( field_pathcustomer_name, typevarchar, semantic_typeSemanticFieldTypeClass.DIMENSION, ), ], upstreams[make_dataset_urn(platform, raw.customers)], ) total_revenue Metric( platformplatform, pathanalytics, idtotal_revenue, semantic_modelstr(model_urn), nameTotal Revenue, descriptionSum of all order amounts., expressionDialectExpressionInput( expressionSUM(ORDERS.amount), dialectDialectClass.SNOWFLAKE ), upstream_datasets[orders_ds.urn], ai_contextAiContextInput(synonyms[revenue]), ) double_revenue Metric( platformplatform, pathanalytics, iddouble_revenue, semantic_modelstr(model_urn), nameDouble Revenue, expression2 * total_revenue, derived_from[total_revenue.urn], ) model SemanticModel( platformplatform, pathanalytics, idorders_model, nameOrders Model, descriptionA semantic model over the raw orders and customers tables., datasets[orders_ds, customers_ds], relationships[ SemanticModelRelationshipInput( from_aliasORDERS, from_columns[customer_id], to_aliasCUSTOMERS, to_columns[customer_id], nameorders_to_customers, cardinalityERModelRelationshipCardinalityClass.N_ONE, ) ], ai_contextAiContextInput( synonyms[orders model], instructionsUse for revenue and customer analytics., ), ) return model, [orders_ds, customers_ds, total_revenue, double_revenue] def main() - None: model, entities build_graph() all_mcps: list[MetadataChangeProposalWrapper] [] all_mcps.extend(model.as_mcps()) for entity in entities: all_mcps.extend(entity.as_mcps()) records: list[dict[str, Any]] [dict(mcp.to_obj()) for mcp in all_mcps] with open(semantic_model_create.json, w) as f: json.dump(records, f, indent2, defaultstr) print(fWrote {len(all_mcps)} MCPs to semantic_model_create.json) # 向真实服务端发出时建议先调用 opt-in 预检助手见下文 # from datahub.sdk import DataHubClient, require_metrics_support # client DataHubClient(server..., token...) # require_metrics_support(client) # raises if the server version is too old # for entity in [model, *entities]: # client.entities.upsert(entity) if __name__ __main__: main()要点说明逻辑数据集的name建议编码为sm_path.sm_id.view_name例如analytics.orders_model.orders_ds保证逻辑数据集在不同 semantic model 之间保持唯一——这一点由 SemanticModelDataset 源码 的文档明确约定每个SemanticFieldInput通过field_pathtype定义字段semantic_type取DIMENSION或MEASURE可选地携带expression多语言方言表达式、aggregation_function、is_time_dimension以及用于 AI 场景的ai_contextMetric的expression支持三种输入形态纯字符串默认按 ANSI SQL 方言、单个DialectExpressionInput、或DialectExpressionInput列表double_revenue展示了不写expression、仅通过derived_from派生自另一个指标的写法。SDK 替你发出了什么对每个 builder 调用entity.as_mcps()时SDK 会生成完整的 aspect 集合并自动装配血缘链实现见 semantic_model.py 与 metric.pysemanticModel一个Status、一个SemanticModelInfoname、description、可选relationships——成员关系不在这里列出以及模型级AiContext仅在非空时发出。从源码看成员关系只存在于成员一侧每个逻辑数据集通过semanticModelProperties.semanticModelIsPartOf指向模型semanticModelInfo上没有datasets/metrics数组[SemanticModel 类文档](https://link.gitcode.com/i/9705b1b974a942664653552b300a072e#L127-L157)。逻辑datasets每个都会带上SubTypes([SEMANTIC_MODEL_DATASET])、一个SemanticModelProperties(alias, semanticModelmodel urn)成员指针IsPartOf、一个包含已声明字段的SchemaMetadata以及——当提供了upstreams时——指向物理数据集的UpstreamLineage。对每个字段SDK 发出锚定在schemaFieldURN 上的semanticFieldAnnotation未提供expression时自动合成为f{alias}.{field_path}并在非空时发出字段锚定的aiContext。metrics每个都会带上Status、MetricInfo含semanticModelmodel urn成员关系ModeledBy与可选expression省略时绝不伪造表达式、MetricRelationships总是发出即使derivedFrom为空这样hasParentMetric才能索引为 false、可选的MetricUpstreams.datasetUpstreams指向指标读取的 Semantic Model Dataset URN以及仅在非空时的AiContext。血缘经由metricUpstreamsMetric → 逻辑数据集和每个逻辑数据集的upstreamLineage逻辑数据集 → 物理数据集形成Metric → Logical Dataset → Physical Dataset。SemanticModel 是成员的容器bounding box不是血缘跳。值得注意的源码细节SemanticModel.as_mcps()在发出时会以strictTrue重新校验 relationshipsjoin 的 alias 必须匹配某个已挂载逻辑数据集的 aliasjoin 列必须出现在该数据集 schema 中列数两侧必须相等别名重复或结构非法时抛出SdkUsageError校验逻辑。SemanticModelDataset._new_from_graph在从服务端读取时绕过严格的__init__字段注解被标记为 create-only读取构造的实例不携带任何字段注解读取路径。期望输出运行示例后当前工作目录会写出semantic_model_create.json。打开它并核对 aspect 形状是否符合生产者契约URN 模式urn:li:semanticModel:(urn:li:dataPlatform:snowflake,analytics,orders_model)、urn:li:metric:(urn:li:dataPlatform:snowflake,analytics,total_revenue)、urn:li:dataset:(urn:li:dataPlatform:snowflake,analytics.orders_model.orders_ds,PROD)逻辑数据集带有Semantic Model Dataset子类型每个逻辑数据集的semanticModelProperties以正确的alias指回模型 URNsemanticFieldAnnotationMCP 锚定在schemaFieldURN 上expression在未显式提供时回退为ORDERS.order_idaiContext只出现在输入非空的字段/实体上build_ai_context在四个字段全空时返回None见 _semantic_shared.pytotal_revenue发出metricUpstreams.datasetUpstreams指向orders_ds的 Semantic Model Dataset URN来自upstream_datasets[orders_ds.urn]。API 参考每个 builder 的完整参数面见 SDK Entities Referencepython-sdk/sdk-v2/entities.mdx位于仓库 python-sdk 文档目录。核心类SemanticModel—datahub.sdk.semantic_model.SemanticModelSemanticModelDataset—datahub.sdk.semantic_model.SemanticModelDatasetMetric—datahub.sdk.metric.Metric常用输入类型均可从datahub.sdk顶层导入输入类型用途说明SemanticFieldInput逻辑数据集的字段field_path、type、semantic_type必填expression省略时自动合成f{alias}.{field_path}SemanticModelRelationshipInput数据集间 join 路径from_alias/to_alias必须与逻辑数据集的alias匹配DialectExpressionInput(dialect, expression) 对可单用、列表使用或包裹在MetricExpressionInputType中AiContextInputaiContextaspect 输入synonyms/instructions/examples/custom_instructions全空则不发 aspect服务端兼容性semanticModel、metric与逻辑dataset实体要求服务端 build 已注册 semantic-model 元数据模型。向未注册这些 aspect 的服务端发出会响亮地失败——服务端拒绝未注册的 aspectemit_mcps抛出异常。如果你想在服务端拒绝之前拿到一个清晰、可操作的错误可在发出前调用 opt-in 的预检助手from datahub.sdk import DataHubClient, require_metrics_support client DataHubClient(server..., token...) require_metrics_support(client) # raises if the server version is too old该助手委托给RestServiceConfig.supports_feature当服务端报告的版本不支持这些实体时抛出异常当没有可检查的版本信号时fail open此时由运维负责确保运行包含该模型的 build。它没有被自动织入DataHubClient.upsert——想要预检时需显式调用。从 实现源码 看其行为更细致一些接受DataHubClient或原始DataHubGraph会自动解包 client 内部的 graph特性检查使用ServiceFeature.SEMANTIC_MODEL_ENTITIES非 semver builddev/snapshot/sha tag会抛ValueError此时 fail open 而不泄漏原始解析错误仅当服务端报告版本低于最低要求、且是托管Cloud服务端时才抛SdkUsageError——OSS/自托管部署不被 SDK 做版本门槛限制避免阻塞所有 OSS 发出路径。逻辑数据集的读-改-写注意事项逻辑数据集SemanticModelDataset上的逐字段semanticFieldAnnotation和字段级aiContext是create-only的逻辑数据集与dataset共用实体类型因此client.entities.get(dataset urn)会把它作为基础Dataset水合——锚定在字段上的注解存在于schemaFieldURN 上而非 dataset 的 aspect 袋中读取时不会被带回。要更新一个逻辑数据集应重新构建一个新的SemanticModelDataset通过schema构造参数重新挂载字段而不是对读回的Dataset做读-改-写。【免费下载链接】datahubThe Context Platform for your Data and AI Stack项目地址: https://gitcode.com/GitHub_Trending/da/datahub创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表