DataHub ODCS 数据契约接入指南:质量规则映射、Schema 合规断言与物理数据集绑定
发布时间:2026/9/19 18:07:01 作者:尧图编辑部 阅读量:1,286

DataHub ODCS 数据契约接入指南质量规则映射、Schema 合规断言与物理数据集绑定【免费下载链接】datahubThe Context Platform for your Data and AI Stack项目地址: https://gitcode.com/GitHub_Trending/da/datahub导读Open Data Contract StandardODCS是 Linux Foundation / Bitol 主导的开放 YAML 数据契约标准。DataHub 的odcs数据源将每一份 ODCS v3.x 契约建模为odcs平台上的逻辑数据集Logical Model并把契约中的quality[]质量规则转换为 DataHub Assertion把契约声明的 Schema 固化为可评估的 Schema 合规断言再通过logicalParent链接将物理数据集与其逻辑模型关联起来。阅读本文后你将掌握 DataHubodcs源完整的质量规则映射规则、物理数据集绑定优先级、关键配置项与常见故障排查方法能够基于当前仓库的 示例 Recipe 独立搭建 ODCS 契约到 DataHub 的完整流水线。本文的主体依据是 odcs_post.md能力细节 / 限制 / 故障排查并结合 模块总览、前置说明 odcs_pre.md、示例 Recipe 以及源码 odcs_source.py、odcs_config.py、odcs_mapper.py 进行纵深补充。一、ODCS 与 DataHub 的建模哲学契约即逻辑数据集ODCS v3 描述的是生产者发布的数据集应是什么样producer-published dataset specification而非生产者与消费者之间的双边协议。因此 DataHub 的odcs源不会把契约建模成一个dataContract实体而是将每个schema[]条目建模为odcs平台上的逻辑数据集每个schema[]条目生成一个独立的逻辑odcsDataset携带datasetProperties、规范 Schema 元数据schemaMetadata、Owner、Tag、源文档链接每个quality[]规则生成一个 Assertion全部挂在逻辑数据集上每个声明了properties的schema[]条目额外生成一个 Schema 合规断言DATA_SCHEMA当schema[]条目能解析到物理数据集由契约中带类型的servers[]推导时源还会用logicalParent即PhysicalInstanceOf关系把物理数据集链接到逻辑数据集断言从不直接写到物理数据集上——期望向物理实例的传播由 DataHub 通过PhysicalInstanceOf关系完成odcs源本身不承担这一职责。以上建模细节在 模块总览的 Concept Mapping 表 中有逐字段的完整对照也是后续所有章节的基础。源码层面这一设计体现在 odcs_source.py 的类注释与capability声明 中源被标记为SupportStatus.ALPHA声明的能力包括 Schema 元数据、Owner、Tag、描述与删除检测通过标准 stateful ingestion其中删除检测只作用于 ODCS 自己拥有的逻辑数据集与 Assertion物理数据集永远不会被标记删除。注意自 v3.0 起一个 ODCS 文件可能描述多张表——每个schema[]条目各成一个逻辑数据集。契约级元数据描述、Owner、顶层 Tag默认复制到每个逻辑数据集上详见下文replicate_contract_metadata的说明。二、质量规则映射Quality Rule Mapping2.1 映射总表每个schema[]表级或properties[]列级quality[]数组中的条目都会变成挂在逻辑odcs数据集上的 DataHub Assertion——无论物理绑定是否解析成功都会发出。核心映射规则如下ODCS 规则DataHub Aspectv3.1metric: nullValues且mustBe: 0FieldAssertionInfoFieldValuesAssertionNOT_NULLv3.1metric: nullValues且阈值为其他值FieldAssertionInfoFieldMetricAssertionNULL_COUNT/NULL_PERCENTAGEv3.1metric: duplicateValues/ v3.0rule: duplicateCount且mustBe: 0FieldAssertionInfoFieldMetricAssertionUNIQUE_PERCENTAGE 100v3.1metric: invalidValuesarguments.validValues/ v3.0rule: validValuesFieldAssertionInfoFieldValuesAssertionINv3.1metric: invalidValues且使用arguments.patternFieldAssertionInfoFieldValuesAssertionREGEX_MATCHmetric: rowCountv3.0 为rule: rowCountVolumeAssertionInfo仅unit: rowstype: sql且带query与可映射阈值SqlAssertionInfotype: customengineimplementationCustomAssertionInfotype enginelogic implementationtype: textCustomAssertionInfologic 描述文本其他带内容但无法精确映射的规则CustomAssertionInfo原规则意图原样保留为logic既无操作符也无主体的规则跳过并告警从源码可以印证这些映射的实现位置NULL_COUNT与NOT_NULL的分流、UNIQUE_PERCENTAGE、REGEX_MATCH等具体映射逻辑集中在 odcs_mapper.py 的断言构造段而断言工作单元的发出流程含rules_routed_to_custom、rules_skipped_no_threshold等上报字段的填充在 odcs_source.py 的_emit_assertions中。2.2 关键语义细节v3.1 的库键是metricrule既被当作 v3.0 的规范键接受也被当作 v3.1 的已弃用别名接受v3.1 契约使用rule会得到一条提示性信息源码中通过trace.deprecated_rule_key上报。每条 Assertion 都会携带 ODCS 来源信息customProperties中的odcs.id、odcs.rule.id、odcs.rule.metric、odcs.rule.unit、序列化的odcs.rule.arguments以及存在时的维度dimension/ 严重级别severity/ 业务影响businessImpactdataPlatformInstance方面将其归属到odcs平台规则提供authoritativeDefinitions时还会附带externalUrl。Assertion URN 由规范中的quality.id播种存在时因此规则改名或顺序调整不会造成身份漂移churn。2.3 路由是精确的不做近似:::warning 路由是精确的没有任何近似完全没有阈值v3.0 的validValues形式与mustBe: 0都表示不允许任何失败行整数的mustBeLessOrEqualTo映射为行unit: rows或百分比unit: percent的失败阈值其余一切——严格小于的容差、非整数的百分比、mustNotBeBetween、重复计数容差、基于百分比的rowCount、多列duplicateValuesarguments.properties、missingValues——都以CustomAssertionInfo形式原样保留其logic承载原始规则的稳定呈现metric、arguments、阈值、unit绝不被近似成某种类型化形态路由到 custom 的规则会列在report.rules_routed_to_custom中完全没有可建模内容的规则会被跳过并列入report.rules_skipped_no_threshold。:::这条宁可用 Custom Assertion 原样保留、也不近似成错误类型化断言的原则是 ODCS 源区别于其他质量规则源的关键设计也是后续故障排查中为什么我的规则显示为 Custom Assertion一节的答案。三、Schema 合规断言Schema-Compliance Assertion对于每个声明了properties的schema[]条目源会在逻辑数据集上发出一个DATA_SCHEMA断言SchemaAssertionInfo把契约声明的 Schema 固化下来——这使得Schema 漂移成为一个可评估的契约违例而不再是隐含问题。schema_assertion_compatibility控制其兼容模式该枚举在 odcs_config.py 中定义取值直接透传给 DataHub 的SchemaAssertionCompatibilityClassSUPERSET默认物理实例必须至少包含契约声明的字段允许额外字段EXACT_MATCH字段集合必须完全一致SUBSET实例字段必须是契约字段的子集。通过emit_schema_assertion: false可以关闭该断言。注意它独立于emit_assertions后者控制quality[]规则的断言两个开关在 odcs_source.py 的_emit_bindings中分别生效。四、物理数据集绑定logicalParent链接绑定存在的目的是把物理数据集链接到其逻辑模型——断言从不依赖绑定即使未绑定断言照常发出。每个schema[]条目的解析按以下优先级进行physical_urn_overrides[contract id][schema entry name]显式指定 URN空字符串表示有意让该条目保持未绑定。映射表中缺失的条目回退到自动推导键与任何 schema 条目都不匹配时给出告警拼写保护。契约的第一个可映射servers[]条目平台来自规范要求的servers[].type或匹配的server_overrides条目表名physicalName回退到name按平台的 URN 约定用 server 自身字段限定ServertypeDataHub 平台物理名Physical namepostgrespostgresdatabase.schema.tableredshiftredshiftdatabase.schema.tablesqlservermssqldatabase.schema.tablesnowflakesnowflakedatabase.schema.table默认小写化lowercase_physical_urns: false可关闭bigquerybigqueryproject.dataset.tabledatabricksdatabrickscatalog.schema.tabletrinotrinocatalog.schema.tablemysqlmysqldatabase.tableoracleoracle不可组合——请提供带点的physicalName或显式 override其他类型—保持未绑定逻辑数据集与断言不受影响从源码看SERVER_TYPE_TO_PLATFORM映射表定义在 odcs_config.py实际覆盖的 type 还包括postgresql → postgres别名LOWERCASE_BY_DEFAULT_PLATFORMS当前仅 snowflake决定了lowercase_physical_urns的默认小写化行为。绑定过程的额外语义已含点的physicalName原样使用视为已预限定并计入report.physical_names_passthrough缺失 server 字段时该条目保持未绑定并给出可操作的原因——源从不猜测 schema 名称默认验证物理 URN 是否存在当 DataHub graph 可用datahub-rest sink且verify_physical_urns_exist开启默认时推导出的 URN 若在 DataHub 中不存在则保持未绑定并告警而不是创建 stub 数据集。对应计数器为report.physical_urns_unverifiedgraph 查询失败时按 fail-open 处理并计入physical_urns_verify_failed文件 sink 无 graph链接不验证直接发出两个 schema 条目绑定同一物理数据集会告警logicalParent是单值的后写者胜出last-writer-wins。源码中同轮冲突通过_seen_physical_urns检测、跨轮冲突通过读取已持久化的LogicalParentClass方面检测并计入physical_urns_link_conflicts详见 odcs_source.py 的_emit_logical_parent。值得强调的是logicalParent工作单元以is_primary_sourceFalse发出——物理数据集属于其平台来源postgres / snowflake 等的源ODCS 从不拥有它这保证了 stateful ingestion 的 stale-entity 删除永远不会软删除物理数据集。五、Recipe 配置参考从本地目录到对象存储与 Git完整的可复制 Recipe 位于 odcs_recipe.yml其核心结构如下source: type: odcs config: # 单个 ODCS YAML 文件、目录或 glob也可以是以上任意组合的列表。 # 每个文件可描述多张表每个 schema[] 条目一张表。 path: ./contracts/5.1 多位置读取对象存储 / HTTP / Gitpath除本地路径外还支持s3://my-bucket/contracts/*.odcs.yaml——需配置aws_connectionaws_region等gs://my-bucket/contracts/*.odcs.yaml——需配置gcs_connectionHMAC 凭据https://example.com/orders.odcs.yaml——仅支持单个文件不支持 glob公开 URL 无需http_connection需认证时配置 bearertoken或 basic-authusername/password二者互斥可信主机可加verify_ssl: false关闭 TLS 校验会触发告警git_info——用 SSH deploy key 浅克隆仓库后扫描此时每个非 URI 的path条目都相对于检出目录解析如path: contracts/或path: **/*.odcs.yaml。在源码中S3/GCS/HTTP 路径的扩展与文件大小上限max_bytes读取实现在 odcs_source.py 的_resolve_remote_uris/_load_remote_yaml且配置校验会在 S3/GCS URI 存在却缺少对应连接块时直接报错odcs_config.py 的object_store_connection_required_for_uris校验器。5.2 绑定相关配置# server_overrides为具名 servers[].server 细化 env / platform_instance / platform # server_overrides: # - server: prod-snowflake # env: PROD # platform_instance: prod # physical_urn_overrides契约 id - schema 条目名 - 显式物理 URN # 空字符串表示有意保持未绑定映射中缺失的名字回退到 server 推导 # physical_urn_overrides: # orders.v1: # orders: urn:li:dataset:(urn:li:dataPlatform:snowflake,prod.sales.orders,PROD) # legacy_orders: ServerMapping还支持match_any: true的通配匹配为所有未被更具体映射覆盖的 server 应用同一 override字段定义与env白名单校验见 odcs_config.py。5.3 开关与微调参数以下为 odcs_recipe.yml 与配置类中带默认值的可选旋钮全部可在config下覆写参数默认值说明verify_physical_urns_existtrue有 DataHub graph 时校验推导 URN 存在再发logicalParent链接lowercase_physical_urnstrue对默认小写化的平台snowflake小写化组合出的物理名emit_assertionstrue是否发出quality[]规则派生的 Assertion挂在逻辑数据集emit_schema_assertiontrue每个schema[]条目发出一个DATA_SCHEMA断言schema_assertion_compatibilitySUPERSET可选EXACT_MATCH/SUBSETemit_logical_parenttrue是否发出物理→逻辑的PhysicalInstanceOf链接tag_prefix无给每个发出的 Tag 加前缀如odcs.strict_validationfalse为true时 JSON Schema 校验失败即跳过契约strip_owner_email_domainfalsealiceacme.com→ corpuseralice与下项互斥owner_email_domain无alice→ corpuseraliceacme.com与上项互斥odcs_versions[3.0.0,3.0.1,3.0.2,3.1.0]apiVersion白名单之外的契约跳过并告警logical_dataset_name_template{contract_id}.{schema_name}逻辑数据集 URN 名模板可用{contract_version}dataset_patternallow all对逻辑数据集名做 allow/deny 正则过滤deny 优先file_extensions[.yaml,.yml,.odcs.yaml,.odcs.yml]目录扫描时视为 ODCS 文件的扩展名max_input_file_bytes5 MB5242880超过此大小的文件解析前即跳过并告警follow_symlinksfalse是否跟随符号链接默认保守防止越出配置根目录replicate_contract_metadatatrue是否在每次摄取时把契约级 Owner/Tag 复制到每个逻辑数据集strip_owner_email_domain与owner_email_domain互斥的约束在 odcs_config.py 的owner_normalization_knobs_are_exclusive校验器 中强制follow_symlinks开启时源码仍会校验符号链接解析后的目标必须位于配置根目录内odcs_source.py 的_accept_symlink_target。六、Limitations明确的范围边界仅支持 ODCS v3.0 与 v3.1。apiVersion报告 v2.x 的契约会跳过并告警。Logical Models 处于 private beta仅在LOGICAL_MODELS_ENABLED开启默认关闭时于 UI 渲染。标志关闭期间逻辑数据集及其断言照常摄取只是不展示。嵌套列断言与字段路径解析字段级断言通过点分属性路径address.city引用列与逻辑数据集自身的schemaMetadata匹配向嵌套结构路径编码方式不同的物理数据集传播时取决于平台的传播机制。属性级unique: true/required: true不会被发出为断言——它们映射进schemaMetadata可空性、键并通过 Schema 合规断言执行如需类型化字段断言请用quality[]规则metric: duplicateValues且mustBe: 0表达唯一性检查。文件加载默认上限 5 MBmax_input_file_bytes更大的 YAML 在解析前跳过并告警。范围外内容SLAslaProperties、support、price、v3.1relationships外键、customProperties→ DataHubcustomProperties只发出odcs.*来源子集、classification→GlossaryTerm链接、schemaField 级logicalParent列链接、ODCS 导出。规范有效但未映射的字段通过report.spec_fields_ignored每文件汇总一次源码中由_warn_unknown_fields三分类走查实现模型已声明字段 / 规范有效但未映射 / 真正未知字段。数据产品 / 输出端口ODPS未建模契约级dataProduct字段仅作为odcs.dataProduct自定义属性发出不链接到 DataHubDataProduct实体ODPS output ports 完全不读取。一份契约跨多个输出端口一个端口挂多份契约目前均不可表示数据集级契约逻辑数据集 其logicalParent链接才是当前支持的单元。Schema 校验依赖随插件打包的 JSON Schemav3.0.2 / v3.1.0 的 Schema 已随插件 vendoredodcs_schema目录版本映射见 odcs_source.py 的_VERSION_TO_SCHEMA因此strict_validation开箱即用若契约声明了受支持apiVersion但缺少对应校验器例如打包回归丢失了 schema 文件契约会不校验地解析而非拒绝——此时strict_validation对这些契约成为 no-op。依赖严格校验作为硬门槛时请确认安装包中确实带有这些 schema 文件。契约元数据复制默认每次运行都会把契约级 Owner 和 Tag 写到每个逻辑数据集。若你在 DataHub UI 中编辑了这些方面下一次摄取会被覆盖设replicate_contract_metadata: false可关闭复制适用于一次性富集工作流。混合平台servers[]绑定使用第一个能映射到平台的 server引用多平台的契约只绑定到那一个。需要按表控制时使用physical_urn_overrides。七、Troubleshooting常见问题排查7.1 发出的断言在哪里看在逻辑odcs数据集上——在 UI 中打开它需要LOGICAL_MODELS_ENABLED查看其Quality / Assertions标签页。该源不向物理数据集写断言DataHub 通过PhysicalInstanceOf关系把期望传播到物理实例。7.2 我的契约没有产生 logicalParent 链接检查report.unmappable_servers与逐条 info 消息契约可能没有声明servers[]、使用了无平台映射的 servertype如kafka、s3或缺少限定表名所需的字段如没有schema的 postgres server。接入 DataHub graph 时report.physical_urns_unverified统计因尚未存在于 DataHub 而被跳过的推导 URN——请先摄取物理平台或设verify_physical_urns_exist: false乐观链接。此外若全部 schema 条目都未解析出绑定运行报告还会给出resolved no physical bindings的提示源码在 odcs_source.py 的收尾逻辑 中专门处理了这个静默陷阱。7.3 逻辑odcs数据集在 UI 中不出现Logical Models 处于 private beta需要LOGICAL_MODELS_ENABLED特性开关默认关闭。开启后即可看到逻辑数据集、其断言与logicalParent链接开关关闭时元数据照常摄取只是不展示。该开关设在 GMS 服务上——DataHub Core 中是datahub-gms容器的LOGICAL_MODELS_ENABLED环境变量DataHub Cloud 请联系管理员开启。7.4missingValues/mustNotBeBetween/ 厂商规则显示为 Custom Assertion这是预期行为。参见上文 质量规则映射 中类型化断言的白名单与阈值可表示性规则白名单之外的规则以CustomAssertionInfo原样保留report.rules_routed_to_custom可查而非近似成错误类型。7.5 我从 ODCS 文件删除了表但物理数据集仍在 DataHub 中这也是预期行为。ODCS 拥有逻辑odcsDataset 及其发出的 Assertion物理 Dataset 属于其平台来源postgres / snowflake / …的源logicalParent链接是非破坏性的富集。启用stateful_ingestion后删除schema[]条目会在下一次 ODCS 摄取时把逻辑数据集及其断言标记为移除——绝不会标记物理数据集。注意其中的不对称性由于物理数据集刻意不进入 ODCS 的 stateful checkpoint其上的logicalParent指针在其逻辑父级被软删除后不会被清除。物理数据集因此会保留一个指向已软删除逻辑数据集的logicalParent直到它下次被重新绑定或人工清理。这是刻意的设计ODCS 绝不能修改它不拥有的物理数据集但确实会留下陈旧指针。7.6 契约 Owner 显示为未解析用户ODCSteam[].username既可以是用户名也可以是邮箱DataHub 会按你的身份源Okta / Azure AD / SCIM / …摄取用户所用的标识符来解析 Owner。两者不一致时契约写aliceacme.com而 DataHub 认识的是alice或反之所有权引用就会悬空。解决方式设置strip_owner_email_domain: true邮箱 → 本地部分或owner_email_domain: acme.com裸用户名 → 邮箱两者之一将契约标识符规整到你的约定显式的urn:li:corpuser:/urn:li:corpGroup:值原样透传。通过 DataHub graph 摄取时无法解析的 Owner 会在运行报告中标记report.owners_unresolved每个唯一 Owner 一条告警——引用仍然发出用户一旦开通即可生效源码实现见 odcs_source.py 的_check_owner_resolution。7.7 我在逻辑数据集上编辑了 Owner下次摄取被还原默认契约级所有权每次摄取都会复制因此任何 UI 编辑都会被覆盖。在源配置中设replicate_contract_metadata: false切换到仅首次出现时发出可在初次摄取后保留 UI 编辑该设置同样作用于顶层 Tag。八、推荐工作流与验证方式综合 odcs_pre.md 的前置说明一份可落地的完整工作流为先用常规源postgres / snowflake / bigquery / …摄取物理平台让物理数据集在 DataHub 中存在用datahub ingest -c recipe.ymlsource.type: odcs摄取 ODCS 契约——注意与已废弃的*.dhub.dc.yamlCLIdatahub datacontract upsert无关后者正在被淘汰在 GMS 上开启LOGICAL_MODELS_ENABLED在 UI 中查看逻辑模型、其断言以及到物理数据集的logicalParent链接按需启用stateful_ingestion需要 DataHub graph 的服务端 checkpointfail_safe_threshold默认 75% 的防护可阻止配置/命名变更引发的大规模删除来清理被删除的schema[]条目对应的逻辑数据集与断言。每次运行结束后建议核对运行报告中的关键计数器contracts_scanned / contracts_parsed / contracts_skipped、logical_datasets_emitted、assertions_emitted、schema_assertions_emitted、physical_bindings_resolved、logical_parents_emitted、rules_routed_to_custom、rules_skipped_no_threshold、physical_urns_unverified、owners_unresolved这些字段统一定义在 odcs_source.py 的ODCSSourceReport中是定位契约没生效 / 没绑定 / 没显示类问题的最快入口。安装依赖时使用pip install acryl-datahub[odcs]以带上 ODCS 相关扩展。【免费下载链接】datahubThe Context Platform for your Data and AI Stack项目地址: https://gitcode.com/GitHub_Trending/da/datahub创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考