| name | configure-quality-rule |
| description | 通过 Dataphin OpenAPI 完成数据质量规则的全生命周期管理:创建监控对象、配置质量规则、设置调度与告警、试跑验证、启停规则、查看执行结果。
当用户场景涉及为某张表/字段配置质量校验、设置质量调度或告警、试跑质量规则、查看质量结果时进入。
触发场景:
- 「给 X 表 Y 字段配非空/唯一/值域/枚举校验」
- 「质量规则要不要试跑 / 质量试跑失败排查」
- 「质量规则挂调度 / 质量告警通知负责人」
触发词:质量监控、质量规则、数据质量校验、质量告警、质量试跑、质量调度、监控对象、validateCondition、upsert-quality-rule。
关键限制 / 类型分支:监控对象类型必须先确认;监控对象名称不可让用户填写;templateId 必须用 list-quality-templates 实测获取;模板级 formProperties 必填项以界面和模板定义为准;validateCondition 无后端默认必须显式传;分区表试跑必须钉单分区;归档模式/计分方式/质量分权重 OpenAPI 不可配。 |
配置数据质量规则(创建 → 调度告警 → 试跑 → 监控)
1. Scenario Description
通过 Dataphin OpenAPI 完成一条质量规则从「监控对象 → 规则 → 调度/告警 → 试跑 → 启停 → 看板」的完整闭环。
核心原则:本 skill 通过 OpenAPI 配置,但目的是让用户在界面上看到的结果与手工配置一致、且能正常运行。因此:
- 必填项以界面为准,不能因 API 允许省略就擅自省略——先与用户确认(见 §6)。
- 监控对象类型必须先确认:
TABLE / DATASOURCE_TABLE / DATASOURCE / INDEX / REALTIME_LOGICAL_TABLE 会决定对象定位方式、创建参数、可用模板和调度边界;不能仅凭对象名猜类型。
- 监控对象名称(WatchName/tableName)不是用户配置项,禁止让用户填写或选择;由 skill 根据目标对象元数据自动生成/回查校验。
- 模板级必填项以模板和界面为准,不能因为
SaveQualityRule.formProperties 顶层标为非必填就传空;例如 TABLE_SCHEMA_CHECK/2600 必须先选校验表并传 dataSourceTable。
- API 无法指定的项(异常归档表、计分方式、质量分权重)必须主动向用户说明默认值。
- 规则模版的必填项都不能为空:
template-config-catalog.json 中 required=true 的配置项必须全部有值。处理方式二选一:
- 有合理默认值 → 自动补上(如
timeTolerance 默认 >0天 且 <1天,validateCondition 默认 ERROR_NUMBER=0)
- 无合理默认值 → 必须询问用户(如
validateField 校验字段、doubleTableCompareTable 比较表、customSql 自定义SQL)
- CLI 无法安全传值 → 创建规则后主动告知用户需到界面手工补充
- 调度、告警由独立命令实现,创建规则前必须分别询问是否需要,不默认配也不默认跳过。
Architecture:Dataphin Tenant + QualityWatch(监控对象) + QualityRule(规则) + QualitySchedule(调度) + QualityAlert(告警)。
2. Installation
仅公共云(A)走 CLI 时需要安装插件;独立部署(B)直调 OpenAPI(见 §3 执行通道)无需安装 CLI 插件。
aliyun plugin install --names aliyun-cli-dataphin-public
(详见 references/cli-installation-guide.md)
3. Environment Variables
凭证与环境变量由父 skill alibabacloud-dataphin-skills 统一声明并预检(父 §3 + §4 Authentication + §8 Step 0,先于路由到本 skill 执行);本 skill 不重复声明。
执行通道(按父 §4.1 自动判定的环境选择,★重要):本 skill 的 OpenAPI Action 与参数语义两套环境一致,但调用通道按部署形态区分,由父 skill alibabacloud-dataphin-skills 的 §4.1 环境自动判定(endpoint / AK 前缀 / 探测,运行时推断,不询问类型)结果决定:
- A
public-cloud(公共云)→ 默认用 CLI:aliyun dataphin-public <命令>(下文各命令),默认 endpoint + aliyun configure 主/子账号 AK。
- B
standalone(独立部署 / POC)→ 默认直接调 OpenAPI,不走 CLI:独立部署环境下 aliyun dataphin-public 对 HTTPS endpoint 会直接报 dial tcp ... connect: bad file descriptor(Go CLI 已知网络层 bug,curl 能通、CLI 不通)。遇到该环境不要再尝试/重试 CLI,直接用阿里云 Python SDK(RPC 风格)调 OpenAPI,自签证书需关闭校验(verify=False / ignore_ssl)。
- Action 名(★POC 实测坑):真实 OpenAPI Action 名 = 对应 CLI kebab 命令的 PascalCase(如
list-quality-watches→ListQualityWatches、upsert-quality-rule→UpsertQualityRule、get-quality-watch-by-object-id→GetQualityWatchByObjectId)。不要猜、也不要沿用文档里可能残留的旧名——PagedQueryQualityWatches/SaveQualityWatch/RemoveQualityRules 这类是旧裸 OpenAPI 命名,POC 直调会报 Unknown API。拿不准就先用 aliyun dataphin-public <command> --cli-dry-run 导出真实 Action 名与参数再调。参数名 kebab-case → camelCase(--watch-type→WatchType),--tenant-id→OpTenantId;复杂对象(--table-info/--validate-condition-list 等)作为 JSON string/list 传同名 camelCase 参数,值语义一致。
- Version / endpoint / 凭证:
Version 以环境实测为准(POC 独立部署实测 2023-06-30);endpoint、AK/SK 从 profile / 环境变量获取。
- Python SDK 骨架 + 签名要点(★POC 实测坑):POC standalone 的 OpenAPI 要求全部业务参数放在 query string 里参与签名;而
aliyunsdkcore 默认会把参数塞进 request body,body 参数不进签名串 → 始终 SignatureDoesNotMatch。所有业务参数一律用 add_query_param 进 query string,禁止用 body(add_body_params);若用 SDK 仍签名不过,改为手动签名 + query string 传参(实测这样 才能正常返回)。
4. Authentication
Pre-check: Alibaba Cloud Credentials Required
Security Rules:
- NEVER read, echo, or print AK/SK values
- NEVER ask the user to input AK/SK directly in the conversation or command line
- NEVER use
aliyun configure set with literal credential values
- ONLY use
aliyun configure list to check credential status
aliyun configure list
Check the output for a valid profile (AK, STS, or OAuth identity).
If no valid profile exists, STOP here.
- Obtain credentials from Alibaba Cloud Console
- Configure credentials outside of this session (via
aliyun configure in terminal or environment variables in shell profile)
- Return and re-run after
aliyun configure list shows a valid profile
Pre-check: Aliyun CLI >= 3.4.8 required
Run aliyun version to verify >= 3.4.8. If not installed or version too low,
install/update from https://aliyuncli.alicdn.com (see references/cli-installation-guide.md for the OS-specific script).
Pre-check: Aliyun CLI plugin update required
[MUST] run aliyun configure set --auto-plugin-install true to enable automatic plugin installation.
[MUST] run aliyun plugin update to ensure that any existing plugins are always up-to-date.
环境选择(A/B)与执行通道:环境由父 §4.1 运行时自动判定(不询问用户类型),据此选通道。通道按 §3「执行通道」选择:A(公共云)→ CLI;B(独立部署)→ 直接调 OpenAPI(Python SDK,verify=False),不要用 CLI(独立部署下 CLI 会报 dial tcp ... bad file descriptor,重试 --endpoint/--skip-secure-verify 也无效)。仅 A 环境走 CLI 时才需 aliyun configure 主/子账号 AK。
5. RAM Policy
最小权限策略详见 ../../ram-policies.md。
[MUST] Permission Failure Handling: When any command or API call fails due to permission errors at any point during execution, follow this process:
- Read
../../ram-policies.md to get the full list of permissions required by this SKILL
- Use
ram-permission-diagnose skill to guide the user through requesting the necessary permissions
- Pause and wait until the user confirms that the required permissions have been granted
6. Parameter Confirmation
IMPORTANT: Parameter Confirmation — Before executing any command or API call,
ALL user-customizable parameters (e.g., RegionId, instance names, CIDR blocks,
passwords, domain names, resource specifications, etc.) MUST be confirmed with the
user. Do NOT assume or use default values without explicit user approval.
6.1 面向普通用户的配置全景(用户模糊表达时先做这一步)
当用户只给模糊指令(如「帮我建个质量监控」),不要直接抛参数术语。先用大白话给「配置全景」,再一步步引导(一次只问一个主题):
一条完整、能正常运行的质量规则主要包含:① 监控对象类型和具体对象(Dataphin 表/全域表/数据源/指标/实时元表);② 查什么问题(非空/唯一/格式/值域/波动);③ 多严格(规则强度 + 校验条件);④ 多久查一次(调度,可选);⑤ 出问题怎么通知(告警,可选);⑥ 其他(异常归档/计分方式,一般默认)。我们先从第 1 步开始:请先确认监控对象类型,再确认具体对象。
若用户已给出明确完整指令,可跳过全景介绍,直接逐项确认缺失/关键项。
6.2 必须澄清的参数
| 参数 | 必填 | 描述 | 默认值 |
|---|
--tenant-id | 是 | 租户 ID(19 位 snowflake,字符串传) | — |
监控对象类型 Type | 是 | 必须最先确认:TABLE Dataphin 表 / DATASOURCE_TABLE 全域表 / DATASOURCE 数据源 / INDEX 指标 / REALTIME_LOGICAL_TABLE 实时元表 | 无 |
| 具体对象 | 是 | 按类型定位真实对象 ID:表 guid/tableId、dataSourceId、indexId 等;对象 ID 必须来自查询结果 | 无 |
规则名称 RuleName | 是 | 规则叫什么;注意这不是监控对象名称 | 无 |
监控对象名称 WatchName/tableName | ✗ | 禁止让用户填写或选择;由 skill 根据元数据自动生成(物理表=项目名.表名,逻辑表=板块名.表名,数据源表=库/schema.表名)并在创建后回查校验 | 自动推导 |
规则强度 RuleStrength | 是 | STRONG(强,阻断下游)/ WEAK(弱,仅告警) | 建议 STRONG,须确认 |
模板级规则配置 formProperties | 是 | 按模板定义补齐,不同模板不同;创建前先查 references/template-config-catalog.json,字段级规则必须有 validateField,值域/时间/一致性/自定义模板按 ruleConfigItems 补齐 | 无 |
校验字段 validateField | 字段级规则必填 | 校验哪个字段(必须从表元数据取真实字段,见 §8 Step 2);表级/数据源级模板不一定有该字段 | 无 |
规则模板 templateId | 是 | 必须通过 list-quality-templates 按当前租户/对象类型实测获取;不要照搬文档示例 ID(速查见 references/quality-config-matrix.md) | 无 |
规则校验 validateCondition | 是 | ❗最关键,无后端默认(不传则 null,界面显示「未配置」,试跑会失败) |
⚠️ 即使用户初始需求没提「调度 / 告警」,也必须主动确认,绝不能因「没提」就默认跳过。
⚠️ 写规则前必须先确认模板级 formProperties:先查 list-quality-templates 得到真实 templateId/templateType,再按 references/template-config-catalog.json 的 supportWatchTypes、validateObjectType、ruleConfigItems 和 references/quality-config-matrix.md 补齐 --form-property-list。FormPropertyList=null 不代表模板无必填项。
界面配置项 ↔ OpenAPI 参数完整对照、validateCondition 结构、模板速查、API 能力缺口,全部见 references/quality-config-matrix.md;31 个系统模板(含 3 个实时元表专用模板 T2700/T2800/T2900)的规则配置项与校验配置项详见 references/template-config-catalog.json。
6.3 监控对象类型先行与创建门控
先确认 Type,再定位对象;不能看到 basic01.account_salesforce 这类名称就默认当作 TABLE。类型会决定对象定位 API、upsert-quality-watch 的对象详情字段、可用模板和调度边界。
| Type | 对象定位结果 | 创建/更新时使用的对象详情 | 是否询问用户 |
|---|
TABLE Dataphin 表 | 表 guid/tableId | --table-info / TableInfo.Id | 不问 ID,自动带入 |
DATASOURCE_TABLE 全域表 | 数据源表 guid/tableId | --table-info / TableInfo.Id | 不问 ID,自动带入 |
DATASOURCE 数据源 | dataSourceId | --data-source-info / DataSourceInfo.Id | 不问 ID,自动带入 |
INDEX 指标 | indexId/indexGuid | --index-info / IndexInfo.Id | 不问 ID,自动带入 |
REALTIME_LOGICAL_TABLE 实时元表 | 实时元表 guid/tableId | --table-info / TableInfo.Id | 不问 ID,自动带入 |
| 全部类型 | QualityOwner | 单个用户 ID | 缺失时才问 |
交互限制:允许在①对象定位不唯一(命中多条)②关键定位信息缺失(如指标缺板块/项目)③缺少 QualityOwner 时向用户确认——此时可主动列出还缺哪些信息、或直接请用户给最直接的 WatchId/indexId;但仍禁止让用户手写 UpsertCommand、table-info、data-source-info、index-info 或监控对象名称。对象详情必须来自前置查询/元数据定位。
7. Observability (MUST follow for every aliyun command)
session-id 由父 skill alibabacloud-dataphin-skills 在套件入口加载时生成(32-char 小写 hex),本子 skill 加载时直接继承同一 session-id,不再重新生成。
Rule: Every aliyun CLI command that calls a cloud API MUST include the --user-agent flag.
Local utility commands (e.g. configure, plugin, version) do not support this flag and should be excluded.
--user-agent AlibabaCloud-Agent-Skills/configure-quality-rule/{session-id}
Example (assuming session-id is a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6):
aliyun dataphin-public get-quality-watch-by-object-id --tenant-id "1234567890123456789" \
--watch-type "TABLE" --watch-object-id "<表ID>" \
--user-agent AlibabaCloud-Agent-Skills/configure-quality-rule/a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
Do not skip, alter the format, or omit --user-agent on any aliyun API command invocation.
8. Core Workflow
变量约定:TENANT_ID(19 位字符串)、SESSION_ID(继承父层)、UA=AlibabaCloud-Agent-Skills/configure-quality-rule/$SESSION_ID。
命令均为插件模式 kebab-case;括号内标注对应 OpenAPI Action 原名,响应字段为 PascalCase(WatchId/RuleId/ScheduleId)。
Step 1: 解析业务维度
用户诉求 → 质量维度:完整性→空值校验;有效性→格式/值域校验;唯一性→唯一性校验;一致性→值一致性比较;稳定性→表波动性校验。
Step 2: 取表字段(配字段级规则前必做,严禁猜字段)
# 已采集表:定位表(catalog 必填,项目名/业务板块名);⚡必带 --cli-query——不带实测单次 115k 字符(每表二十多字段全量元数据)
aliyun dataphin-public list-tables --tenant-id "$TENANT_ID" \
--catalog "<项目名>" --keyword "<表名>" \
--cli-query 'PageResult.TableList[].{Name:Name,TableId:TableId,Guid:Guid}' \
--user-agent "$UA" # 注意:扁平参数,无 --list-query
# 已采集表:拉字段列表(返回 Name/DataType/Pt/AllowEmpty/Cn);⚡必带 --cli-query 裁剪——全量返回单表实测 18k 字符,裁剪后 ~2.5k(-86%)
aliyun dataphin-public get-table-columns --tenant-id "$TENANT_ID" \
--catalog "<项目名>" --table-name "<表名>" \
--cli-query 'ColumnList[].{Name:Name,DataType:DataType,Pt:Pt,AllowEmpty:AllowEmpty,Cn:Cn}' \
--user-agent "$UA"
⚠️ 未采集的外部数据源表 list-tables/get-table-columns 拿不到字段:改用「数据库SQL任务」execute-ad-hoc-task 直连数据源跑 SELECT * FROM 库.表 LIMIT 1 取字段(公共云 A / 独立部署 B 同一套),详见 references/quality-config-matrix.md §7。
Step 3: 定位/创建监控对象(线性主路径,勿绕圈)
先按 §6.3 确认监控对象类型 Type,然后严格按 ①→②→③ 线性走,全程只围绕「监控对象」本身,不要在「找资产」上绕圈:
① 查监控对象是否已存在 → ListQualityWatches(CLI list-quality-watches),把用户给的信息全部映射成过滤参数(类型→--watch-type-list、板块→--biz-unit-name-list、项目→--project-name-list、负责人→--*-owner-list;--keyword 只对表名有效,别拿它搜指标)。
aliyun dataphin-public list-quality-watches --tenant-id "$TENANT_ID" \
--watch-type-list '["INDEX"]' \
--biz-unit-name-list '["LD_train"]' --project-name-list '["train"]' \
--page-no 1 --page-size 100 --user-agent "$UA"
在返回列表按英文 code / 中文名匹配目标。命中 → 复用其 WatchId,直接跳到 Step 4;命中多条 / 关键信息不够 → 直接问用户补 <板块/项目/负责人> 或给 WatchId,不自行盲搜。
② 不存在 → 新建监控对象(先拿对象 ID):
- 表(TABLE / DATASOURCE_TABLE) → 用
list-tables --catalog <项目/板块名> --keyword <表名> 定位 tableId(见 Step 2)。
- 指标(INDEX) → 无 list 接口可搜,直接请用户提供
indexId(或让用户先在界面建好监控对象,回到 ① 查)。
拿到对象 ID 后 upsert-quality-watch(真实 Action UpsertQualityWatch)。门控:Type + 单个 QualityOwner + 按类型对象详情,不让用户自由填一堆字段。创建报错 → 原样告知并引导用户订正(确认 Type/对象是否存在/是否已发布/catalog),不吞错、不盲搜。
③ 拿到 WatchId → 进入 Step 4 创建质量规则。
⚠️ 避坑清单(POC 实测,点开)
- 别只靠
--keyword 搜:Keyword 定义是「监控表名称」,对 INDEX 指标匹配不到;指标靠「板块 + 项目 + 类型」过滤。
- 别用
GetBizMetricByName / list-catalog-assets 找监控对象:前者只查业务指标 BIZ_INDEX(查不到技术指标);后者只查资产目录已上架资产,而监控对象取自「资产清单」,大量搜不到。表→list-tables,指标→直接要 indexId。
- Action 名:真实名 = CLI 命令的 PascalCase;旧裸名
PagedQueryQualityWatches / SaveQualityWatch POC 直调报 Unknown API,拿不准用 --cli-dry-run 导出。
ListQualityWatches 完整过滤参数:--watch-type-list / --biz-unit-name-list(板块) / --project-name-list(项目) / --index-owner-list·--table-owner-list·--quality-owner-list / --data-source-id-list·--data-source-type-list / --keyword(仅表名) / --page-no / --page-size。
- 已知对象 ID 时直接精确查
get-quality-watch-by-object-id --watch-type <Type> --watch-object-id <对象ID>。
# TABLE / DATASOURCE_TABLE / REALTIME_LOGICAL_TABLE:用 --table-info
aliyun dataphin-public upsert-quality-watch --tenant-id "$TENANT_ID" \
--type "TABLE" --quality-owner "<单个用户ID>" \
--table-info '{"tableId":"<id>","tableName":"<自动推导全名>","dataSourceId":"<id>"}' \
--user-agent "$UA"
# DATASOURCE:用 --data-source-info
aliyun dataphin-public upsert-quality-watch --tenant-id "$TENANT_ID" \
--type "DATASOURCE" --quality-owner "<单个用户ID>" \
--data-source-info '{"dataSourceId":"<dataSourceId>","dataSourceName":"<name>","dataSourceType":"<type>","dataSourceEnv":"PROD"}' \
--user-agent "$UA"
⚠️ 监控对象名称(WatchName/tableName)禁止让用户自填;需要 tableName 时由 skill 从元数据自动生成全名(物理表=项目名.表名 / 逻辑表=板块名.表名 / 数据源表=库或schema.表名),创建后再用 get-quality-watch-by-object-id / get-quality-watch 回查展示名。
⚠️ 数据源类型监控对象用 --data-source-info(而非 --table-info),内部字段按当前 CLI 契约;旧 API/封装里曾出现 dataSource 驼峰字段坑,实际写入前以 --help 和返回为准。
⚠️ 逻辑表必须在 --table-info 传完整字段(tableType=LOGIC_DIM_TABLE/tableCatalog/projectId/bizUnitId/dataSourceId),仅传 tableId 会「半创建」——接口虽返回 WatchId,但后续 upsert-quality-schedule/upsert-quality-watch-alert 报 DPN.UniversalQuality.watchTableNotExists。完整字段清单见 references/quality-config-matrix.md §9。
Step 4: 选模板 + 创建规则(★写操作,先确认,见 §8 执行前确认)
# 先查当前租户/当前对象类型支持的真实模板。不要照搬文档示例 templateId。
aliyun dataphin-public list-quality-templates --tenant-id "$TENANT_ID" \
--watch-type-list "TABLE" "DATASOURCE_TABLE" \
--template-source-list "SYSTEM" --page-no 1 --page-size 100 \
--user-agent "$UA"
# 独立部署/env23 示例:--endpoint 不带 https://
aliyun --profile env23 dataphin-public list-quality-templates \
--endpoint dataphin-openapi.env23.aliyun.com \
--op-tenant-id 300001414 \
--watch-type-list TABLE DATASOURCE_TABLE \
--template-source-list SYSTEM \
--page-no 1 --page-size 100 --format json \
--user-agent "$UA"
# 单模板详情(可查 Id/Name/Type/Catalog;注意某些环境 FormPropertyList 可能为 null)
aliyun dataphin-public get-quality-template --tenant-id "$TENANT_ID" \
--quality-template-id "<templateId>" --user-agent "$UA"
# 组装规则配置前,读取 references/template-config-catalog.json:
# - supportWatchTypes:确认当前监控对象类型是否支持
# - validateObjectType:COLUMN 需 validateField,TABLE 不需要校验字段
# - ruleConfigItems:逐项补齐 --form-property-list(Name/Value)
# - validateConfigItems.metric.options:选择合法校验指标
# 创建规则;--validate-condition-list 为★关键必填、无默认
# ⚠实测(env23 2023-06-30):--form-property-list 键名必须是 Name/Value(PascalCase),
# 误用 propertyName/propertyValue 会导致 validateField 不生效、模板变量 ${validateField} 不被替换、试跑 FAILED。
# ⚠--validate-condition-list 是扁平数组 + id/parentId 父子关联(不是嵌套 subConditions),否则报 "validate config miss param id"。
# ⚠必须有 RELATION 根节点——单条件也不例外:第一个元素必须是 type=RELATION 根(operator=OR/AND、无 parentId),
# 所有 EXPRESSION 用 parentId 挂到它下面;绝不能把单个 EXPRESSION 当根直接传。否则界面「校验配置→规则校验」
# 识别不了裸 EXPRESSION,「统计指标」显示为空/未配置(INDEX 指标类规则尤为典型,POC 实测已复现)。
aliyun dataphin-public upsert-quality-rule --tenant-id "$TENANT_ID" \
--quality-rule-name "<名>" --strength "STRONG" --watch-id "<wid>" \
--template-id 100 --template-type "FIELD_NULL_VALUE_VALIDATE" \
--catalog-list "COMPLETENESS" \
--form-property-list '{"Name":"validateField","Value":"<字段>"}' \
--validate-condition-list '{"id":"<uuid-root>","type":"RELATION","operator":"OR"}' '{"id":"<uuid-expr>","parentId":"<uuid-root>","type":"EXPRESSION","operator":"EQUAL","metric":"ERROR_NUMBER","value":"0"}' \
--enable-error-archive true \
--user-agent "$UA" # → 返回 RuleId
list-quality-templates 返回结构以当前 CLI 为准,env23 实测为 PageResult.QualityTemplateList[],字段为 Id/Name/Type/Catalog,不是旧文档里的 Data.data.TemplateId。
模板级必填项门控:FormPropertyList=null 不代表该模板没有界面必填项;创建前必须按 references/template-config-catalog.json 的 ruleConfigItems 逐项判断必填项。字段级模板(validateObjectType=COLUMN)必须传 validateField;表级模板(validateObjectType=TABLE)不传校验字段;模板动态配置如 contentIdentifyMethod、valueRangeType、timeTolerance、statisticalMethod、customSql 等按 JSON 中的 required/options 组装。
两表/跨源比较表字段名:界面“选择比较表”识别的 formProperty 名称是 doubleTableCompareTable,不是旧脚本里的 doubleCompareTable。T800/T1600/T1700/T1750/T1800 等两表模板必须传:{"Name":"doubleTableCompareTable","Value":"{\"doubleTableCompareTable\":\"项目或数据源目录.表名\",\"doubleTableCompareField\":\"比较字段\"}"};否则 get-quality-rule 虽可能看到 doubleCompareTable,但界面“选择比较表”仍为空。
两表/跨源关联表达式写法:doubleTableJoinCondition 必须传表达式字符串,不是 {leftField/rightField/operator} JSON。内置数据表参数:T1 为检测表,T2 为比较表;标准示例:{"Name":"doubleTableJoinCondition","Value":"T1.id = T2.id"}。
T1800 两表字段业务逻辑写法:contentIdentifyExpression 必须传业务逻辑表达式,并用 ${T1.字段名} / ${T2.字段名} 变量引用实际表字段,不能写裸字段名如 col1=col2。T1 为检测表,T2 为比较表,最多支持双表;示例:{"Name":"contentIdentifyExpression","Value":"${T1.total_sales}=${T2.unit_price}*${T2.sales_volume}"}。表达式中的变量还必须逐个实例化:去掉 ${} 后的变量名作为独立 formProperty.Name,实际字段作为 Value,例如 {"Name":"T1.total_sales","Value":"total_sales"}、{"Name":"T2.unit_price","Value":"unit_price"}、。两表类还需传关联方式:,并配合 和 。
:枚举不是只传 ,而是外层 + 内层 JSON 字符串两层结构。env23 实测 返回:
Step 5: 调度与告警(先分别询问是否需要)
# 调度三步:查已有 → 创建 → 绑定(仅创建调度不会自动绑定!)
aliyun dataphin-public get-quality-schedules-by-watch-id --tenant-id "$TENANT_ID" --watch-id "<wid>" --user-agent "$UA"
aliyun dataphin-public upsert-quality-schedule --tenant-id "$TENANT_ID" \
--upsert-quality-schedule-name "<调度名>" --watch-id "<wid>" \
--type "PERIOD_SCHEDULE" --cron-expression "0 0 2 * * ?" --user-agent "$UA" # → ScheduleId
# ⚠实测(env23):--rule-id-list/--schedule-id-list 必须空格分隔多值(不是逗号);
# 本命令即使入参无效也会静默返回 {"Success":true},绑定并不生效!
aliyun dataphin-public assign-quality-rule-of-all-rule-scope-schedules --tenant-id "$TENANT_ID" \
--watch-id "<wid>" --rule-id-list <rid1> <rid2> --schedule-id-list <sid> --user-agent "$UA"
# ⚠绑定后必须回查确认:get-quality-rule 返回的 QualityRuleInfo.ScheduleBindList 应为
# [{"ScheduleId":<sid>,...}],若为 null 则未绑定成功。(调度侧 IsRefByRule 恒为 null,不可用于判断)
aliyun dataphin-public get-quality-rule --tenant-id "$TENANT_ID" --quality-rule-id "<rid>" --user-agent "$UA" # 校验 ScheduleBindList
# 告警(watch 级别,对该表所有规则生效);--quality-alert-info 为内嵌 JSON
aliyun dataphin-public upsert-quality-watch-alert --tenant-id "$TENANT_ID" \
--watch-id "<wid>" \
--quality-alert-info '{"alertQualityOwner":true,"alertQualityOwnerChannels":["MAIL"]}' --user-agent "$UA"
★调度类型(--type)必填,不得为空,也不得默认:创建调度前必须让用户从以下 5 个枚举值中显式指定要创建哪种调度,禁止 Agent 擅自默认或留空:
PERIOD_SCHEDULE 定时调度(cron 周期触发)
MANUAL_SCHEDULE 手动触发(不设周期,仅手动/试跑触发)
CODE_CHECK_TRIGGER 代码检查触发 / 数据更新触发(产出该对象的加工任务运行时触发)
STATIC_TASK_TRIGGER 固定任务触发(指定真实调度节点 + 触发时机)。触发时机 --trigger-type 必填且 3 选 1,需给用户推荐:ALL_TASKS_FINISHED(所有任务成功后——多上游合并产出)/ ONE_TASKS_FINISHED(每个任务每次成功后——多来源/分区增量即时校验)/ PRE_ONE_TASKS_START(每个任务每次运行前——源表前置质量卡口);详见 references/quality-config-matrix.md §4
DEPENDENCY_SCHEDULE 依赖调度
★调度类型 × 监控对象类型支持矩阵(仅列 3 种核心触发式调度):
| 监控对象类型 | 定时 PERIOD_SCHEDULE | 数据更新触发 CODE_CHECK_TRIGGER | 固定任务触发 STATIC_TASK_TRIGGER |
|---|
TABLE Dataphin 表 | ✅ | ✅ | ✅ |
DATASOURCE_TABLE 全域表 | ✅ | ❌ | ✅ |
DATASOURCE 数据源 | ✅ | ❌ | ✅ |
INDEX 指标 | ✅ | ✅ | ✅ |
REALTIME_LOGICAL_TABLE 实时元表 | ✅ | ✅ | ✅ |
即:TABLE/INDEX/REALTIME_LOGICAL_TABLE 支持全部 3 种;DATASOURCE_TABLE/DATASOURCE 只支持定时 + 固定任务触发,不支持数据更新触发(OpenAPI 对其配 CODE_CHECK_TRIGGER 不报错但语义不该配,须自行规避)。/ 为合法枚举值,与对象类型的支持关系以界面为准。
:
Step 6: 试跑验证(★默认收尾动作,先问一句)
# 分区表试跑必须钉单分区:--partition-expression-from CUSTOM + --partition-expression "ds=<真实分区值>"
aliyun dataphin-public submit-quality-rule-tasks --tenant-id "$TENANT_ID" \
--is-test-run true \
--watch-rule-id-list '{"watchId":"<wid>","ruleId":"<rid>"}' \
--partition-expression-from "CUSTOM" --partition-expression "ds=20160710" \
--user-agent "$UA" # → RuleTaskId
aliyun dataphin-public get-quality-rule-task --tenant-id "$TENANT_ID" --rule-task-id "<tid>" --user-agent "$UA"
aliyun dataphin-public get-quality-rule-task-log --tenant-id "$TENANT_ID" --rule-task-id "<tid>" --user-agent "$UA"
★分区表必须钉单分区(真实分区值 + --partition-expression-from CUSTOM),否则 OneService 拒绝全表扫描报错;真实分区值用「数据库SQL任务」跑 SHOW PARTITIONS 读取(见 quality-config-matrix.md §7)。
★判定结果三态:status=SUCCESS+validateResult=true→通过;SUCCESS+false→校验不通过(真实检出异常,规则有效);status=FAILED→执行报错(非校验不通过,真因看 log)。切勿只看 validateResult 下结论。
★试跑报错就直接抛出 + 分析日志给建议,不要一直卡着:只要试跑任务触发成功(已拿到 RuleTaskId),轮询后无论 status=FAILED(执行报错)还是 SUCCESS+validateResult=false(校验不通过),都不要反复重跑 / 静默重试 / 停在原地干等。标准动作:① 立即 get-quality-rule-task-log 拉错误日志;② 把关键报错原样抛给用户(错误码 / 报错行 / 缺失字段 / 函数签名不匹配等);③ 基于日志给出具体修改建议(如字段类型不符→换时间类型字段或改自定义 SQL;分区未钉→补 --partition-expression;validateCondition 缺失/缺 RELATION 根→按下方「常见坑」补齐;SQL 语法/权限错→指出对应行),可对照下方「常见坑」与 §8 各字段门控;④ 交回用户决策,由其订正后再决定是否重跑。试跑失败不删除、不回滚已创建的规则(见「执行前确认」,试跑结果仅如实告知)。
Step 7: 开启校验开关
aliyun dataphin-public update-quality-rule-switch --tenant-id "$TENANT_ID" \
--open true --rule-id-list "<rid>" --user-agent "$UA"
Step 8: 定期检查与看板
aliyun dataphin-public get-quality-watch-task --tenant-id "$TENANT_ID" --watch-task-id "<wtid>" --user-agent "$UA" # 查监控任务详情
aliyun dataphin-public list-quality-rule-tasks --tenant-id "$TENANT_ID" --watch-task-id "<wtid>" --user-agent "$UA" # 按 watchTaskId 查每条规则的执行结果
aliyun dataphin-public list-quality-rules --tenant-id "$TENANT_ID" --watch-id "<wid>" --user-agent "$UA" # 按 watchId 查规则定义与状态
⚠️ 两者不可互替:list-quality-rules 按 watch-id 查规则定义/状态;list-quality-rule-tasks 按 watch-task-id 查每条规则的执行结果。
执行前确认(写操作必备 / HITL)
本 skill 涉及写操作(upsert-quality-watch / upsert-quality-rule / upsert-quality-schedule / assign-quality-rule-of-all-rule-scope-schedules / upsert-quality-watch-alert / submit-quality-rule-tasks / update-quality-rule-switch)。调用 upsert-quality-rule 之前必须向用户完整复述配置清单(表 / 字段 / 模板 / 维度 / 规则强度 / validateCondition / 归档 / 调度 / 告警)并明确请求确认:
- 用户确认 → 执行;确认即承诺,此后即使试跑失败也不删除、不回滚规则(试跑结果仅如实告知)。
- 用户未确认 → 一条规则都不创建。
- 仅当创建过程中途某步 API 报错(产生半成品)时,才清理本次已建规则/调度以保持原子性。
仅当用户明确回复「确认 / yes / 执行」后才发起写命令。
9. Success Verification
重要原则:命令行返回 Code: OK / Success:true 只表示请求受理,不等于界面配置完整。最终以 Dataphin 界面实际可见状态为唯一可信事实;自动化侧必须通过 get-quality-watch*、list-quality-rules、get-quality-rule、get-quality-rule-task* 等回查验证配置是否完整、规则是否启用、调度是否绑定、试跑是否成功。
三步法:
- 同步返回
Code: OK ≠ 业务成功(写命令返回的 WatchId/RuleId 非空才算受理)。
list-quality-rules 反查命中新建规则,ruleStatus 正确。
- 异步状态轮询:
get-quality-rule-task 的 status(INIT/RUNNING/SUCCESS/FAILED)+ validateResult;FAILED 时 get-quality-rule-task-log 看真因。
详见 references/acceptance-criteria.md。
10. Cleanup
# 解除调度绑定(如需)
aliyun dataphin-public remove-quality-rule-schedules --tenant-id "$TENANT_ID" \
--watch-id "<wid>" --rule-id "<rid>" --schedule-id-list "<sid>" --user-agent "$UA"
# 关闭规则
aliyun dataphin-public update-quality-rule-switch --tenant-id "$TENANT_ID" \
--open false --rule-id-list "<rid>" --user-agent "$UA"
已确认创建的规则默认保留;仅在中途报错产生半成品时清理本次资源。
11. Command Tables
详见 references/related-commands.md。
12. Best Practices + Reference Links
- 大整数 ID(19 位 snowflake)一律字符串传参,示例中用引号包住。
- 写操作(upsert/assign/submit/switch)执行前必须 HITL 二次确认。
- 监控对象类型是首问项;对象 ID、WatchName/tableName、复杂对象 JSON 均由查询结果自动推导,禁止让用户手写。
templateId 必须用 list-quality-templates 按当前租户/对象类型实测获取,不能照搬文档示例。
formProperties 必须按模板级必填项补齐;FormPropertyList=null 不能作为空配置依据;31 个系统模板以 references/template-config-catalog.json 为准。
validateCondition 无后端默认,任何模板都必须显式传,否则界面显示「未配置」且试跑失败。
- 分区表试跑 / 调度必须钉真实单分区,避免全表扫描被拒。
- 调度需
assign-quality-rule-of-all-rule-scope-schedules 显式绑定,仅创建不生效。
✗ 平台限制
✗ 归档模式 / 归档位置 / 计分方式 / 质量分权重 OpenAPI 不可配
- 限制描述:
upsert-quality-rule 请求参数不含这些字段,创建后后端自动填默认(归档=仅归档异常字段、位置=默认文件服务器、计分=质量校验状态、权重=1)。
- 替代方案:如需自定义只能到界面手工操作。
✗ 单规则级告警不支持
- 限制描述:告警是 watch 级别,对该监控对象下所有规则生效。
- 替代方案:N/A(无法按单规则配)。
常见坑
[用户纠偏] 独立部署 CLI 报 bad file descriptor → 改走 OpenAPI 直调
- 现象:独立部署/POC 环境下
aliyun dataphin-public 对 HTTPS endpoint 直接报 dial tcp ... connect: bad file descriptor,curl 能通但 Go CLI 不通;加 --endpoint/--skip-secure-verify/重试均无效。
- 结论:这是 POC 独立部署已知 CLI 网络层 bug。判定为独立部署时默认直接调 OpenAPI(阿里云 Python SDK,RPC,自签证书
verify=False),不要再走 CLI;公共云才用 CLI。详见 §3「执行通道」。
[用户纠偏] OpenAPI 直调报 Unknown API → Action 名用 --cli-dry-run 导出
- 现象:独立部署直调 OpenAPI 时,用文档里的
PagedQueryQualityWatches/SaveQualityWatch 等名报 Unknown API;换用 --cli-dry-run 导出才拿到真实名 ListQualityWatches/UpsertQualityRule 等。
- 根因:
PagedQuery*/Save*/Remove* 是旧裸 OpenAPI 命名;POC 的 CLI 插件对应的真实 Action 名 = CLI kebab 命令的 PascalCase(list-quality-watches→ListQualityWatches、upsert-quality-rule→UpsertQualityRule)。
- 结论:拿不准就
aliyun dataphin-public <command> --cli-dry-run 导出真实 Action 名与参数再用 Python SDK 调;不要硬编码/猜名。详见 §3「执行通道」。
[用户纠偏] POC 直调签名失败 SignatureDoesNotMatch → 业务参数必须进 query string 参与签名
- 现象:Python SDK 直调 OpenAPI 签名始终失败(
SignatureDoesNotMatch),即使 AK/SK 正确、Action 名正确、endpoint 可达。
- 根因:POC standalone 要求业务参数放在 query string 里参与签名;而
aliyunsdkcore 默认把参数塞进 request body,body 参数不进签名串 → 签名不一致。
- 结论:所有业务参数用
add_query_param 进 query string,禁用 body(add_body_params);SDK 仍不过就手动签名 + query string 传参(实测 ListQualityWatches 可正常返回)。详见 §3 Python SDK 骨架与签名要点。
[用户纠偏] 卡在“找资产” → 有效信息全用上查 watch,不够就主动问用户
- 现象:为定位对象 ID 反复用
GetBizMetricByName/ListTables(draft true/false、多种名称组合)都返回「资产不存在」,卡住无法推进;或只用 --keyword 搜指标 code 搜不到(Keyword 只匹配「监控表名称」,对 INDEX 无效)。
- 结论:不要盲搜资产。① 把用户给的有效信息全部映射成
ListQualityWatches 过滤参数(类型→--watch-type-list、板块→--biz-unit-name-list、项目→--project-name-list、负责人→--index-owner-list 等),命中就复用 WatchId;② 命中多条 / 关键信息不足 → 主动告知用户还缺什么、或直接要 WatchId/indexId;③ 确认无 watch 需新建但缺对象 ID:表用 list-tables 定位,指标无 list 接口可搜→直接请用户给 indexId(不能用 list-catalog-assets 兜底,它只查资产目录已上架资产,监控对象取自资产清单);④ 创建报错原样告知并引导。详见 §8 Step 3。
[Agent 自主发现] validateCondition 不传 → 规则不完整
- 现象:
upsert-quality-rule 不传 --validate-condition-list 时,界面打开显示「未配置」,试跑失败。
- 结论:任何模板都必须显式传
validateCondition,空值/唯一校验推荐 ERROR_NUMBER=0。
[用户纠偏] 缺 RELATION 根节点 → 界面「统计指标」为空
- 现象:
--validate-condition-list 只传了单个 EXPRESSION(当根节点、无 parentId),或漏了 type=RELATION 根。虽然 get-quality-rule 能查到 Metric,但界面「校验配置→规则校验」的「统计指标」显示为空/未配置。INDEX(指标)稳定性/波动性规则尤为典型。
- 根因:界面按「RELATION 根 + 其下 EXPRESSION(
parentId 关联)」的嵌套语义解析,识别不了裸 EXPRESSION。
- 结论:条件列表第一个元素必须是
type=RELATION 根(operator=OR/AND),所有 EXPRESSION 通过 parentId 挂到根(或内层 RELATION)下——单条件也不例外。复杂多指标「与/或」写法见 references/quality-config-matrix.md §2。
[用户纠偏] 只看 API 顶层必填 → 漏掉模板级必填项
- 现象:
SaveQualityRule.formProperties / CLI --form-property-list 顶层看似可选,规则也可能返回创建成功,但界面里模板配置为空或必填项缺失。
- 例子:
TABLE_SCHEMA_CHECK / templateId 2600「表结构异动监测」在界面必须选择校验表;创建时必须传 dataSourceTable(完整表元数据 JSON),不能传空 formProperties。
- 结论:创建规则前先查
list-quality-templates 获取真实 Id/Type/Catalog,再按模板定义和界面必填项补齐 --form-property-list。
[用户纠偏] templateId 不能照搬文档示例
- 现象:文档示例里的模板 ID 在目标租户可能不存在,直接创建会报模板不存在。
- 结论:使用
list-quality-templates 按 --watch-type-list / --template-source-list SYSTEM 查询当前租户真实模板;env23 实测返回在 PageResult.QualityTemplateList[] 中,字段为 Id/Name/Type/Catalog。
[Agent 自主发现] timeTolerance(时间差)必须传 3 元素 JSON 数组
- 现象:T600/T700/T800 时间类模板的
timeTolerance 是 TIME_TOLERANCE 复合组件。早期传单对象 JSON(如 {"unit":"d","value":"1","operator":"<"})或简单字符串(如 <1d)导致后端数据损坏:get-quality-rule 返回 InternalError,拖垮 list-quality-rules 接口。
- 根因:后端期望
timeTolerance 的 Value 是 3 元素 JSON 数组(条件1 + 条件2 + 比较类型),传单对象格式触发反序列化异常。
- 正确格式:
Value=[{"checked":true,"operate":">","time":0,"type":"DAY"},{"checked":true,"operate":"<","time":1,"type":"DAY"},{"timeCompareMethod":"VALIDATE_SUB_COMPARE"}]
- 结论:
timeTolerance 可以通过 CLI 正确传值,必须使用 3 元素 JSON 数组格式,默认建议 >0天 且 <1天。
[Agent 自主发现] 时间类模板字段必须是日期时间类型
- 现象:T600/T700/T800 试跑报
Semantic analysis exception - function datediff cannot match any overloaded functions with (BIGINT, BIGINT, STRING)。
- 根因:时间类模板底层生成
datediff(校验项, 比较项, '单位'),但配置时把 id 等 BIGINT 字段填到了 validateField/validateItem/compareItem,导致 datediff(BIGINT, BIGINT, STRING) 无可匹配重载。
- 结论:时间类模板只能选择
DATE/DATETIME/TIMESTAMP/TIMESTAMP_NTZ 等真实时间字段或时间表达式;禁止用 BIGINT 主键、订单号、时间戳数字、yyyymmdd 数字直接配置。若业务时间存为 BIGINT,需提供转换后的时间字段,或改用自定义 SQL 模板显式转换。
[Agent 自主发现] 分区表试跑不指定分区 → 全表扫描被拒
- 现象:分区表试跑不带
--partition-expression 时报 full scan with all partitions。
- 结论:用
partitionType=CUSTOM + 具体真实分区值钉单分区(连唯一性校验也钉单分区)。
Reference Links