Quellcode durchsuchen

docs(kb): UDF 手册骨架搭建

tianyu.chu vor 2 Wochen
Ursprung
Commit
1b40b68d83
4 geänderte Dateien mit 16 neuen und 18 gelöschten Zeilen
  1. 1 2
      kb/30-开发规范.md
  2. 10 9
      kb/31-UDF手册.md
  3. 3 6
      kb/90-重构路线.md
  4. 2 1
      kb/92-重构进度.md

+ 1 - 2
kb/30-开发规范.md

@@ -347,11 +347,10 @@ flowchart LR
 3. **文件头必须声明元信息**:作者、日期、工单号、目的、执行状态(待执行 / 已执行 yyyy-mm-dd)
 4. **`fix/` 和 `backfill/` 强制 Review**:涉及线上数据订正和历史回刷的脚本,合并前至少 1 人 Review
 5. **与 `jobs/` 的边界**:
-   - 表结构变更 → **只在 `manual/ddl/` 写一个新的 ALTER 文件**,**不要回头改 `manual/ddl/{表名}.sql`**(migration 模式,详见 `00-项目架构.md` §9.6)。`jobs/` 里没有 CREATE TABLE 可改
+   - 表结构变更 → **只在 `manual/ddl/` 写一个新的 ALTER 文件**,**不要回头改 `manual/ddl/{表名}.sql`**(migration 模式,详见 `00-项目架构.md` §9.6)。
    - 历史数据回刷 → 优先复用 `jobs/` 原 SQL + 日期参数,`manual/backfill/` 只放调用包装
    - 临时取数给业务方 → `manual/adhoc/`
    - 脏数据订正 → `manual/fix/`,必须附 TPAD 工单号
-6. **归档策略**:执行完成后保留 3-6 个月作为审计证据,过期后移入 `manual/archive/` 或直接删除
 
 ## 6. 相关文档
 

+ 10 - 9
kb/31-UDF手册.md

@@ -1,16 +1,17 @@
 # UDF 手册
 
-`dw_base/udf/common/` 下通用 UDF 的自查表:每次增删 / 重命名 / 改签名时同步更新本表。
-业务专用 UDF 放 `dw_base/udf/business/`,不走本表,由各 business 子目录自己的 README 维护。
+`dw_base/udf/` 下 UDF 的自查表:每次增删 / 重命名 / 改签名时同步更新本表。
 
-## 1. 准入规则
+## 1. 通用 UDF 自查表
 
-待通用 UDF 注释统一化首版落地、本表登记全量函数后写入。
+| 函数编号 | 函数名 | 分类 | 入参 | 返回 | 描述 | 示例 | 补注释状态 |
+|----------|--------|------|------|------|------|------|------------|
+| —        | —      | —    | —    | —    | —    | —    | —          |
 
-## 2. 自查表
+> 本表行数应等于 `spark_common_udf.py` 中导出的 UDF 函数数(启动日志里 `注册 Python UDF` 的条数即真值)。
 
-| 函数名 | 分类 | 入参 | 返回 | 摘要 | 代码位置 | 补注释状态 |
-|--------|------|------|------|------|----------|------------|
-| — | — | — | — | — | — | — |
+## 2. 业务 UDF 自查表
 
-> 分类由 `dw_base/udf/common/spark_common_udf.py` 中的实际划分为准;本表行数应等于 `spark_common_udf.py` 中导出的 UDF 函数数(启动日志里 `注册 Python UDF` 的条数即真值)。
+| 函数编号 | 函数名 | 分类 | 入参 | 返回 | 描述 | 示例 | 补注释状态 |
+|----------|--------|------|------|------|------|------|------------|
+| —        | —      | —    | —    | —    | —    | —    | —          |

+ 3 - 6
kb/90-重构路线.md

@@ -546,23 +546,20 @@ record_per_channel = 100000
 **问题**:
 - 注释不一致导致业务 SQL 开发时需要反复读源码猜参数语义,违背 common/ auto-load 的"开箱即用"初衷
 - 未来新增通用 UDF 如果没有登记表,规模大了之后"这个函数有没有 / 叫什么 / 谁加的"全靠 grep
-- 业务 UDF 进 common 的准入标准缺失,容易出现"为了省事放 common"与"只在一处用也塞 common"两类误伤
 
 **目标态**:
 
 1. **注释完整化**:40 函数全部补齐 docstring,统一 5 段模板 —— 一句话摘要 / 入参(名 · 类型 · 约束 / 可空 / 单位) / 返回(类型 · 语义 · 空值场景) / 异常与边界 / SQL 调用示例。按分类分批推进:JSON 段 → Array 段 → String 段 → Numeric-Date-Hash 段 → Cross-type 段,5 批独立 commit。
 
-2. **UDF 自查表**:新建 `kb/31-UDF手册.md`(与 `30-开发规范.md` 同级独立文档;40 函数规模独立成文更稳,新增 UDF 需要稳定引用锚点)。表头 `函数名 | 分类 | 入参 | 返回 | 摘要 | 代码位置 | 补注释状态`。初版把现有 40 函数全量登记,后续新增通用 UDF(进 `common/`)必须同步登记此表;只进 `business/` 的 UDF 不走此表,在 `business/` 子目录 README 维护。
-
-3. **注册准入规则**:在 `kb/30-开发规范.md` 新增一节或 `kb/31-UDF手册.md` 内嵌一节写硬约束 —— 向 `common/` 增删 UDF 前,先读 `kb/31` 自查表;新增必须同步更新表(函数名 / 分类 / 示例),否则 commit 不过。与 `tests/unit/udf/test_spark_common_udf.py`(阶段 4 首批单测目标,见 §2.11 占位 registry)是配套的:自查表为开发者服务,单测为回归服务。
+2. **UDF 自查表**:新建 `kb/31-UDF手册.md`(与 `30-开发规范.md` 同级独立文档;40 函数规模独立成文更稳,新增 UDF 需要稳定引用锚点)。表头 `函数编号 | 函数名 | 分类 | 入参 | 返回 | 描述 | 示例 | 补注释状态`,函数编号由 Codex 在 `spark_common_udf.py` 中以顺序注释注入(不依赖行号,避免改动污染他函数)。common 与 business 两类 UDF 都在本表登记,分两段(§1 通用 / §2 业务);初版由 Codex 补注释完成后登全量。
 
 **回归检验**:
 - 任意 SQL 文件直接 `SELECT my_udf(col)` 能跑通(common auto-load 链路未变,保留现状)
 - 自查表行数 = `spark_common_udf.py` 中 `@udf` / `def` 导出函数数(启动日志中 `注册 Python UDF` 的条数即真值)
 
 **与其他条目的关系**:
-- 2026-04-20 UDF 模块重组(kb/92)已完成重组动作,本节是其延伸(补注释 + 登记表 + 准入规则
-- 不动 auto-load 机制(`bin/spark-sql-starter.py` + `dw_base/__init__.py:29 COMMON_SPARK_UDF_FILE` 常量),只补文档与规则
+- 2026-04-20 UDF 模块重组(kb/92)已完成重组动作,本节是其延伸(补注释 + 登记表)
+- 不动 auto-load 机制(`bin/spark-sql-starter.py` + `dw_base/__init__.py:29 COMMON_SPARK_UDF_FILE` 常量),只补文档
 
 ## 三、`__init__.py` 瘦身(高优先级) [聚簇 B(B1)]
 

+ 2 - 1
kb/92-重构进度.md

@@ -178,9 +178,10 @@
 | 2026-04-20 | **存储格式约定反转:`orc.compress` 不显式写 `NONE`,走 ORC 默认(ZLIB)**:`workspace/20260420/dim_pub_calendar_ful_o.sql` 建表时写了 `TBLPROPERTIES ('orc.compress' = 'NONE')`,核查 ORC 默认压缩为 ZLIB,NONE 是显式关闭压缩(非 no-op)。前期 kb 三处口径"咱不压缩放弃磁盘换 CPU"属于过早决策,小表省 CPU 微乎其微、业务表规模上来后 ZLIB 更优,维护一套"显式写 NONE"的约束成本大于收益。改为走默认、建表不加 `TBLPROPERTIES`。文档同步三处:`kb/20-数仓分层与建模.md §7` 压缩行(`orc.compress=NONE` → 走 ORC 默认)、`kb/00-项目架构.md §9.1` 末尾存储格式约定行(删 `+ orc.compress=NONE`)、`kb/00-项目架构.md` raw 层 CTAS 样例(删 `OPTIONS ('orc.compress'='NONE')` 一行)。未在文档里加"为什么不显式写 NONE"的解释性注释(见用户反馈) | — |
 | 2026-04-20 | **kb/20 分区/raw STRING 口径收敛**:§7 分区字段补 `dt` 类型 `STRING` + 格式 `YYYYMMDD`(如 `20260101`);§8.1 "全字段 STRING" bullet 去掉 "(不含 `dt` 分区)"(dt 本身也是 STRING,括号让人误以为 dt 是另一种类型) | — |
 | 2026-04-20 | **raw EXTERNAL 规范硬化:kb/00 §9.2 CTAS 样例改 INSERT OVERWRITE**:关闭上一批 changelog 的"CTAS + EXTERNAL 冲突待拍"。(a) kb/00 §9.2 CSV 一次性导入样例从 CTAS 改为预建 `EXTERNAL TABLE` + `INSERT OVERWRITE` 两步;"CTAS vs INSERT OVERWRITE" 对照表替换为"raw 层写入模式对照"(3 个场景全部 `EXTERNAL` + `INSERT OVERWRITE`);"为什么 CSV 一次性导入推荐 CTAS" 论证段删除(论点作废);raw 层不再有"省 manual/ddl/"的例外。(b) kb/20 §8.1 "全字段 STRING" bullet 改为 "raw 层所有表字段(含 `dt` 分区)一律 STRING 类型"(与 §7 dt STRING 规范对齐,消除"业务字段 vs 分区字段"的措辞分裂) | — |
-| 2026-04-20 | **kb/90 新增 §2.12 通用 UDF 注释完整化 + 自查表(聚簇 B 延伸)**:`dw_base/udf/common/spark_common_udf.py` 40 函数注释粗细不一,且当前 common/ auto-load 链路没有任何"新增 UDF 需要登记哪里"的准入规则。三档改造:(a) 40 函数 docstring 统一 5 段模板(摘要 / 入参 / 返回 / 异常与边界 / SQL 示例),按 JSON → Array → String → Numeric-Date-Hash → Cross-type 5 批分 commit;(b) 新建 `kb/31-UDF 手册.md`(与 `30-开发规范.md` 同级独立文档,方案 A 而非并入 30),表头 `函数名 / 分类 / 入参 / 返回 / 摘要 / 代码位置 / 补注释状态`,初版登记 40 函数全量,新增通用 UDF 进 common/ 时必须同步登记;business/ UDF 在自己的子目录 README 维护,不走此表;(c) `kb/30-开发规范.md` 或 `CLAUDE.md` 加硬约束"增删 common/ UDF 先读 kb/31 + 同步更新",与 `tests/unit/udf/test_spark_common_udf.py`(§2.11 占位 registry 登记的阶段 4 首批单测目标)配套(自查表为开发者服务,单测为回归服务)。本条是 2026-04-20 UDF 模块重组(本 changelog 之前记录的 UDF 6 文件合一 + business/common 分离)的延伸,不动 auto-load 机制,只补文档与规则 | — |
+| 2026-04-20 | **kb/90 新增 §2.12 通用 UDF 注释完整化 + 自查表(聚簇 B 延伸)**:`dw_base/udf/common/spark_common_udf.py` 40 函数注释粗细不一,且当前 common/ auto-load 链路没有任何"新增 UDF 需要登记哪里"的准入规则。三档改造:(a) 40 函数 docstring 统一 5 段模板(摘要 / 入参 / 返回 / 异常与边界 / SQL 示例),按 JSON → Array → String → Numeric-Date-Hash → Cross-type 5 批分 commit;(b) 新建 `kb/31-UDF 手册.md`(与 `30-开发规范.md` 同级独立文档,方案 A 而非并入 30),表头 `函数名 / 分类 / 入参 / 返回 / 摘要 / 代码位置 / 补注释状态`,初版登记 40 函数全量,新增通用 UDF 进 common/ 时必须同步登记;business/ UDF 在自己的子目录 README 维护,不走此表;(c) 注册准入规则(于 2026-04-21 评估取消,详见当日 changelog)。本条是 2026-04-20 UDF 模块重组(本 changelog 之前记录的 UDF 6 文件合一 + business/common 分离)的延伸,不动 auto-load 机制,只补文档与规则 | — |
 | 2026-04-20 | **dw_base 占位模块骨架 + tests 骨架 + bin 收口(B4 提前 + C 起步)**:(a) 新建 5 个占位模块 `dw_base/io/{db,file,hdfs}/` + `dw_base/ops/` + `dw_base/pm/` + `dw_base/dq/` + `dw_base/sync/`,每个带 `__init__.py` + `README.md`(4 节:职责/接口/依赖/状态);实现留待后续阶段。(b) `tests/{unit,integration}/` 骨架 + `tests/README.md` + `.gitkeep`;首批单测目标 `tests/unit/udf/test_spark_common_udf.py`(40 函数)。(c) `bin/excel_to_hive.py` 删除(一次性工具,有需求重做);`publish.sh` 从项目根 `git mv` 到 `bin/publish.sh`(publish 是 DS 调度入口 = 和 bin 同类)。代码侧单次 commit `6936460`。(d) 文档侧同步:`kb/30-开发规范.md §4.5 占位模块规范`(4 节标准 + "空 __init__.py 无 README → 删"铁律);`kb/90-重构路线.md` 按聚簇 + DAG 重组(新增 §〇 全景与 DAG、§2.10 common/utils/io/ops 四模块律、§2.11 新占位 registry、§六.1 tests 骨架标注、§八 从 P0-P3 线性表替换为聚簇 A-F 推进视图;所有主章节加 `[聚簇 X]` 标签;§2.1 publish.sh 行改为 `bin/publish.sh`);本文档总览引入聚簇视图说明 + 阶段 1/2/4 状态改"推进中 / 部分提前完成" | — |
 | 2026-04-21 | **kb/30 §4.6 整合 Git 协作规范**:`kb/inbox/git规范.md` 草稿 6 章整合进 kb/30 §4.6(§4.5 与 §5 之间),节号重排为 §4.6.1~§4.6.6 对齐现有多级风格;草稿 §六 "命名规范" 改名为 "分支 / Tag 命名" 避开与 `kb/21-命名规范.md` 主文档重名;补分支/hotfix/tag 命名示例到各 3 个(个人分支 3 个与 §4.6.1.2 ASCII 图的李四/王五/张三对齐) | — |
 | 2026-04-21 | **kb/30 大梳理:删 §1 通用开发流程 / §4.5 占位模块规范,Commit 信息归入 Git 协作节,整体节号重排**:(a) 删 §1 通用开发流程(与项目无针对性);(b) 删 §4.5 占位模块规范(该规范仅用于架构规划专用、非普通开发内容,迁至项目根 `CLAUDE.md`);(c) 原 §4.4 Commit 信息(Conventional Commits)并入 Git 协作规范作为 §3.4.7;(d) 节号重排 §2→§1 TPAD / §3→§2 数仓流程 / §4→§3 代码开发(§4.1-§4.3→§3.1-§3.3、§4.6→§3.4,其 §4.6.1-6 → §3.4.1-6)/ §5→§4 / §6→§5 / §7→§6;(e) 联动 `kb/README.md` §30 条目描述 + `kb/90-重构路线.md §2.11` 占位模块标准引用从 `kb/30 §4.5` 改指 `CLAUDE.md` | — |
 | 2026-04-21 | **datasource 目录结构收敛到 kb/00 §1 一处**:老 kb 内 datasource 目录树在 kb/00 §1(扁平老结构)、kb/00 §6.4(带 env 层目标态)、kb/02 §4(带 env 层)三处平行画,一改就易漏。kb/00 §1 子树补齐 env 层 + 实例举例(`postgresql/{prod,test,dev}/hobby.ini`)作为唯一真源;kb/00 §6.4 删内嵌目录示例块 + 删"当前状态:尚未落地"段(按"不标现状/目标态,以目标态为准"约定);kb/02 §4 删重复目录树,改跨文档引 `kb/00 §1` | — |
 | 2026-04-21 | **kb/31-UDF手册.md 骨架建立**(聚簇 B / §2.12(b) 启动):新建独立文档作为 `dw_base/udf/common/` 通用 UDF 自查表的稳定锚点;仅骨架(概述 + 准入规则占位 + 空表头),分类不预划由 Codex 按 `spark_common_udf.py` 实际划分登记;`kb/README.md` §3x 加入口。配套修正 `kb/90 §2.12`:(a) 文件名 `kb/31-UDF 手册.md` → `kb/31-UDF手册.md`(无空格);(b) 准入规则落点候选从 `kb/30 或 CLAUDE.md` 改为 `kb/30 或 kb/31 内部`(规范类条款不进 CLAUDE.md)。首版全量登记 + 硬约束正文待 Codex UDF 注释统一化落地后另起 changelog | — |
+| 2026-04-21 | **kb/31 表头定稿 + 合并 common/business + 取消 UDF 准入规则**:(a) kb/31 表头改为 `函数编号 \| 函数名 \| 分类 \| 入参 \| 返回 \| 描述 \| 示例 \| 补注释状态`,函数编号由 Codex 在 `spark_common_udf.py` 以顺序注释注入(不依赖行号,避免改动污染其他函数);(b) business UDF 纳入 kb/31 第二段(原"business 在子目录 README 维护,不走此表"规划取消);(c) UDF 准入规则取消(无执行主体,规则无意义)。联动 `kb/90 §2.12`:删"业务 UDF 进 common 准入标准缺失"问题项、同步新表头、删"business 不走此表"表述、删"注册准入规则"整点、关系节去"准入规则"字样;`kb/92` L181 历史条目 (c) 改软标注指向本条。另 `kb/30 §5` 删"jobs/ 里没有 CREATE TABLE 可改"冗余句与"归档策略"防御性条款 | — |