Kaynağa Gözat

refactor(udf): 删 geo_hash UDF 及 pygeohash 依赖,新项目暂无 geo 场景

tianyu.chu 2 hafta önce
ebeveyn
işleme
5b2569a712

+ 0 - 5
dw_base/udf/common/spark_common_udf.py

@@ -16,7 +16,6 @@ from collections import Counter
 from datetime import datetime
 from datetime import datetime
 from typing import Dict, List, Union
 from typing import Dict, List, Union
 
 
-import pygeohash
 from pyspark.sql.functions import udf
 from pyspark.sql.functions import udf
 from pyspark.sql.types import (
 from pyspark.sql.types import (
     ArrayType, BooleanType, FloatType, IntegerType, LongType, MapType,
     ArrayType, BooleanType, FloatType, IntegerType, LongType, MapType,
@@ -372,10 +371,6 @@ def min_value(*args):
     return mini_value
     return mini_value
 
 
 
 
-def geo_hash(latitude: float, longitude: float, precision: int) -> str:
-    return pygeohash.encode(latitude, longitude, precision)
-
-
 def millis_timestamp_to_str(ts: int, str_format: str = None) -> str:
 def millis_timestamp_to_str(ts: int, str_format: str = None) -> str:
     date_time = datetime.fromtimestamp(ts / 1000.0)
     date_time = datetime.fromtimestamp(ts / 1000.0)
     if str_format:
     if str_format:

+ 1 - 1
kb/90-重构路线.md

@@ -664,7 +664,7 @@ tests/
 | **强依赖(KEEP)** | 留在 `requirements.txt` | pyspark / pandas / pymongo / PyMySQL / requests / PyYAML / findspark / python-dateutil / wheel / pytest |
 | **强依赖(KEEP)** | 留在 `requirements.txt` | pyspark / pandas / pymongo / PyMySQL / requests / PyYAML / findspark / python-dateutil / wheel / pytest |
 | **无引用(DROP)** | 直接移除 | openvino / transformers / scikit-learn / scipy / numpy / Flask / matplotlib / lxml / SQLAlchemy / jieba / cpca / openpyxl / xlrd / 等 20+ 个 |
 | **无引用(DROP)** | 直接移除 | openvino / transformers / scikit-learn / scipy / numpy / Flask / matplotlib / lxml / SQLAlchemy / jieba / cpca / openpyxl / xlrd / 等 20+ 个 |
 | **stdlib 冗余(STDLIB)** | 移除 backport | `configparser` —— Python 3 标准库自带,backport 安装反而会覆盖 stdlib |
 | **stdlib 冗余(STDLIB)** | 移除 backport | `configparser` —— Python 3 标准库自带,backport 安装反而会覆盖 stdlib |
-| **弱依赖(LAZY)** | **不写进 requirements**,用到时手动 pip install | elasticsearch / pyhive / redis / cryptography / oss2 / fuzzywuzzy / pygeohash / pypinyin —— 都只被即将清理的老业务代码引用 |
+| **弱依赖(LAZY)** | **不写进 requirements**,用到时手动 pip install | elasticsearch / pyhive / redis / cryptography / oss2 / fuzzywuzzy / pypinyin —— 都只被即将清理的老业务代码引用 |
 
 
 **后续事项**:
 **后续事项**:
 
 

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

@@ -168,6 +168,7 @@
 | 2026-04-20 | **alerter + datax-speed 扩展名统一为 `.ini` + alerter 口径统一为"入库"**:(a) `conf/alerter.conf` → `conf/alerter.ini` + 从 gitignore 改为入库;反转 2026-04-15 changelog(line 139)当时记的 `.conf` + gitignore 口径。理由:项目 conf/ 全部 ini + 代码侧 `configparser` 使用 10+ 次 + `PyYAML` 在 requirements 但零 `import yaml`(躺尸依赖)→ ini 是事实标准;webhook key 低敏(最多被拿去发垃圾消息,非账密级)+ 部署靠 git pull,gitignore 会让 bigdata / DolphinScheduler 拉不到配置。结构:`[common] url_prefix` + `[channels] ba/dcp/etl/skb/realtime = <key>`。(b) `conf/datax-speed.conf` → `conf/datax-speed.ini`,同一口径收敛,消除 `.conf/.ini` 混用。同步点:kb/00 §6 sparkconfig 表告警 Webhook 行(gitignore 列 `是` → `否`)、kb/90 §2.1 硬编码表 alerter 行 / §2.4 目录树 / §2.9 整节 4 处、kb/92 阶段 2 checklist 4 处(line 62 去掉"敏感文件"措辞、line 66 改为入库、line 78 钉钉条删除合并入 line 79、line 91 扩展名改)、记忆 `project_templates_and_config` 去掉"kb/92 一致性提醒"段(已消除)。**未改动**:2026-04-15 changelog line 139(历史快照保留)、2026-04-18 changelog line 153(历史快照保留)、`workers.conf` 扩展名 + kb/90 §2.1 里"ini 或 yaml 格式"未定的表述(不在本批范围,用户后续拍板) | — |
 | 2026-04-20 | **alerter + datax-speed 扩展名统一为 `.ini` + alerter 口径统一为"入库"**:(a) `conf/alerter.conf` → `conf/alerter.ini` + 从 gitignore 改为入库;反转 2026-04-15 changelog(line 139)当时记的 `.conf` + gitignore 口径。理由:项目 conf/ 全部 ini + 代码侧 `configparser` 使用 10+ 次 + `PyYAML` 在 requirements 但零 `import yaml`(躺尸依赖)→ ini 是事实标准;webhook key 低敏(最多被拿去发垃圾消息,非账密级)+ 部署靠 git pull,gitignore 会让 bigdata / DolphinScheduler 拉不到配置。结构:`[common] url_prefix` + `[channels] ba/dcp/etl/skb/realtime = <key>`。(b) `conf/datax-speed.conf` → `conf/datax-speed.ini`,同一口径收敛,消除 `.conf/.ini` 混用。同步点:kb/00 §6 sparkconfig 表告警 Webhook 行(gitignore 列 `是` → `否`)、kb/90 §2.1 硬编码表 alerter 行 / §2.4 目录树 / §2.9 整节 4 处、kb/92 阶段 2 checklist 4 处(line 62 去掉"敏感文件"措辞、line 66 改为入库、line 78 钉钉条删除合并入 line 79、line 91 扩展名改)、记忆 `project_templates_and_config` 去掉"kb/92 一致性提醒"段(已消除)。**未改动**:2026-04-15 changelog line 139(历史快照保留)、2026-04-18 changelog line 153(历史快照保留)、`workers.conf` 扩展名 + kb/90 §2.1 里"ini 或 yaml 格式"未定的表述(不在本批范围,用户后续拍板) | — |
 | 2026-04-20 | **DS 残留清理 + workers / spark-defaults 扩展名收敛**:(a) DS 残留:`dw_base/ds/` 目录在 `f20d9c3` 就随老业务批被删,但前瞻 kb 未同步 —— 本次清 `kb/00-项目架构.md:42` 目录树 `ds/` 行 + `:122` Mermaid 节点 `DS_API` + `:169` Mermaid 边 `DS_API --> DS` + `kb/90-重构路线.md:70-72` 目标态目录树 `ds/` 子树 3 行。(b) `conf/workers.conf` → `conf/workers.ini`(kb/90 §2.1 硬编码表 + §2.4 目录树 + kb/92 checklist 2 处),并把 §2.1 里"ini 或 yaml 格式"的未决表述锁死为"ini 格式"—— 与本项目 Python 读配置统一走 configparser 的约定一致(见上一条 alerter 口径)。(c) `conf/spark-defaults.yaml` → `conf/spark-defaults.conf`(**Spark 原生 flat `spark.x.y  value` 格式,非 ini**):反转中途一度采纳的"全部配置 `.ini` 统一"结论,理由是该文件是 `$SPARK_HOME/conf/spark-defaults.conf` 的克隆(运维熟悉、与 `spark-submit --properties-file` 原生兼容、代码侧零映射转换、无 section 前缀/key 拼接 tax)。§2.3 草案块从 `[executor]/[driver]/[sql]/[default]` section + configparser + `spark.{section}.{key}` 拼接的写法,整段改写为 flat key-value;`_load_default_config()` 从 configparser 改为 10 行手写解析器。同步点:kb/90 §2.1 硬编码表 + §2.3 整节(草案 + 代码要点 + 两个落地坑 4 处引用)+ §2.4 目录树、kb/00 §6 配置分类表 + §6.2 三级覆盖图 + §6.2 说明段(启动加载方式从 "configparser" 改为 "Spark 原生 key value")、kb/92 checklist 2 处、记忆 `project_templates_and_config` 扩展名约定段追加 spark-defaults.conf 例外说明。**未改动**:2026-04-15 changelog line 134(`conf/spark-defaults.yaml` 历史快照保留)。**路线外变更同步入册原则**:DS 目录删除在 `f20d9c3` 未同步 kb 前瞻文档,属于此前"默默做完"漏记,本次补 | — |
 | 2026-04-20 | **DS 残留清理 + workers / spark-defaults 扩展名收敛**:(a) DS 残留:`dw_base/ds/` 目录在 `f20d9c3` 就随老业务批被删,但前瞻 kb 未同步 —— 本次清 `kb/00-项目架构.md:42` 目录树 `ds/` 行 + `:122` Mermaid 节点 `DS_API` + `:169` Mermaid 边 `DS_API --> DS` + `kb/90-重构路线.md:70-72` 目标态目录树 `ds/` 子树 3 行。(b) `conf/workers.conf` → `conf/workers.ini`(kb/90 §2.1 硬编码表 + §2.4 目录树 + kb/92 checklist 2 处),并把 §2.1 里"ini 或 yaml 格式"的未决表述锁死为"ini 格式"—— 与本项目 Python 读配置统一走 configparser 的约定一致(见上一条 alerter 口径)。(c) `conf/spark-defaults.yaml` → `conf/spark-defaults.conf`(**Spark 原生 flat `spark.x.y  value` 格式,非 ini**):反转中途一度采纳的"全部配置 `.ini` 统一"结论,理由是该文件是 `$SPARK_HOME/conf/spark-defaults.conf` 的克隆(运维熟悉、与 `spark-submit --properties-file` 原生兼容、代码侧零映射转换、无 section 前缀/key 拼接 tax)。§2.3 草案块从 `[executor]/[driver]/[sql]/[default]` section + configparser + `spark.{section}.{key}` 拼接的写法,整段改写为 flat key-value;`_load_default_config()` 从 configparser 改为 10 行手写解析器。同步点:kb/90 §2.1 硬编码表 + §2.3 整节(草案 + 代码要点 + 两个落地坑 4 处引用)+ §2.4 目录树、kb/00 §6 配置分类表 + §6.2 三级覆盖图 + §6.2 说明段(启动加载方式从 "configparser" 改为 "Spark 原生 key value")、kb/92 checklist 2 处、记忆 `project_templates_and_config` 扩展名约定段追加 spark-defaults.conf 例外说明。**未改动**:2026-04-15 changelog line 134(`conf/spark-defaults.yaml` 历史快照保留)。**路线外变更同步入册原则**:DS 目录删除在 `f20d9c3` 未同步 kb 前瞻文档,属于此前"默默做完"漏记,本次补 | — |
 | 2026-04-20 | **`DATAX_HOME` 条件赋值 + 默认值对齐新环境(§2.1 最小铺垫)**:`bin/common/init.sh:17` 从 `DATAX_HOME="/opt/module/datax"` 改为 `DATAX_HOME="${DATAX_HOME:-/opt/datax}"`。触发:dim_calendar 测试同步在服务器上报 `/opt/module/datax/bin/datax.py` 不存在,实际新 CDH 环境 DataX 装在 `/opt/datax`。两步改动:(a) 默认值从 tendata 时代的 `/opt/module/datax` 更正为新项目真实路径 `/opt/datax`,(b) 改为 `${VAR:-default}` 条件赋值,允许 shell 环境 override(未来多机器部署路径不一致时零代码改动)。未做:§2.1 完整外配到 `conf/env.sh` 仍待推进。同步更新 `kb/90-重构路线.md §2.1` 表格对应行的当前值与备注 | — |
 | 2026-04-20 | **`DATAX_HOME` 条件赋值 + 默认值对齐新环境(§2.1 最小铺垫)**:`bin/common/init.sh:17` 从 `DATAX_HOME="/opt/module/datax"` 改为 `DATAX_HOME="${DATAX_HOME:-/opt/datax}"`。触发:dim_calendar 测试同步在服务器上报 `/opt/module/datax/bin/datax.py` 不存在,实际新 CDH 环境 DataX 装在 `/opt/datax`。两步改动:(a) 默认值从 tendata 时代的 `/opt/module/datax` 更正为新项目真实路径 `/opt/datax`,(b) 改为 `${VAR:-default}` 条件赋值,允许 shell 环境 override(未来多机器部署路径不一致时零代码改动)。未做:§2.1 完整外配到 `conf/env.sh` 仍待推进。同步更新 `kb/90-重构路线.md §2.1` 表格对应行的当前值与备注 | — |
+| 2026-04-20 | **删除 `geo_hash` UDF + `pygeohash` 依赖(重构计划外)**:`spark-sql-starter.py` 在新 CDH 环境启动时报 `ModuleNotFoundError: No module named 'pygeohash'`(`dw_base/udf/common/spark_common_udf.py:19 import pygeohash`)。根因:2026-04-20 UDF 重组(kb/92:165)把 `geo_hash(lat, lng, precision)` 保留进 `common/`(auto-load),但 `pygeohash` 在 kb/90 §7.1 还标 LAZY 且注释"只被即将清理的老业务代码引用"—— UDF 进 common 后该分类失效。当前阶段业务 SQL 尚未开始,`geo_hash` 零现成消费者;真需要 geo 分析再从老项目 copy + 放 `business/`。整改:(a) 删 `spark_common_udf.py:19 import pygeohash` + `:375-376 def geo_hash(...)`;(b) kb/90 §7.1 LAZY 行的 `pygeohash` 移除(仓库零引用,不需要 LAZY 档) | — |
 | 2026-04-20 | **kb/00 目录树同步真实状态 + §2/§3 收敛**:`dw_base/` 实际子目录已变(2026-04-20 删 `scheduler/` / `hive/`,新建占位 `io/` / `ops/` / `dq/` / `pm/` / `sync/`),kb/00 §1 目录树仍停留在旧态;§2 核心模块职责表 + §3 Mermaid 均与 §1 同一信息三视图重复。整改:(a) §1 目录树同步真实子目录,职责并入每行行尾注释;顺带补漏 `publish.sh` 已挪入 `bin/`(`6936460`)+ 新增 `tests/` 条目 + `conf/` 注释更新为"非敏感入库"口径;(b) §2 表删除,替换为一行"职责已并入 §1"指引;(c) §3 Mermaid 删除,保留标题 + 一行"待基础模块实装后重绘"说明。保留 §2/§3 heading 保证节号稳定,外部引用(kb/90 §4.3/§5/§6.4/§9、kb/30 §8/§9.6)零更新 | — |
 | 2026-04-20 | **kb/00 目录树同步真实状态 + §2/§3 收敛**:`dw_base/` 实际子目录已变(2026-04-20 删 `scheduler/` / `hive/`,新建占位 `io/` / `ops/` / `dq/` / `pm/` / `sync/`),kb/00 §1 目录树仍停留在旧态;§2 核心模块职责表 + §3 Mermaid 均与 §1 同一信息三视图重复。整改:(a) §1 目录树同步真实子目录,职责并入每行行尾注释;顺带补漏 `publish.sh` 已挪入 `bin/`(`6936460`)+ 新增 `tests/` 条目 + `conf/` 注释更新为"非敏感入库"口径;(b) §2 表删除,替换为一行"职责已并入 §1"指引;(c) §3 Mermaid 删除,保留标题 + 一行"待基础模块实装后重绘"说明。保留 §2/§3 heading 保证节号稳定,外部引用(kb/90 §4.3/§5/§6.4/§9、kb/30 §8/§9.6)零更新 | — |
 | 2026-04-20 | **恢复 `dw_base/__init__.py:16` 的 `HADOOP_CONF_DIR` export(反转 2026-04-18 第四轮决策的一小部分)**:`spark-sql-starter.py -f workspace/20260420/select_dim_calendar_dw2.sql` 在新 CDH 环境报 `When running with master 'yarn' either HADOOP_CONF_DIR or YARN_CONF_DIR must be set` —— Spark on YARN 启动时 `SparkSubmitArguments.validateSubmitArguments` 强校验该 env;bigdata 账号 shell 里未 export。2026-04-18 第四轮决策(`kb/92:158`)把这行当"死代码"删,判断只基于 DataX JVM(DataX 确实不靠它,HA 走 ini `[hadoop_config]` 注入),忽略了同一 `dw_base/__init__.py` 也是 Spark 入口的 bootstrap。本次恢复:`os.environ['HADOOP_CONF_DIR'] = '/etc/hadoop/conf'` 加回,注释更新为"Spark 需要;DataX 不读 classpath"。同步更新 `kb/90 §2.8` 末尾"死代码"段(重写为"仅对 Spark 生效")+ §2.8 代码改造清单附表对应行(从"删除"改为"保留",给出双路径理由)。DataX 侧结论(ini `[hadoop_config]` 注入 HA、`HADOOP_CONF_DIR` 对 DataX JVM 无效)不受影响 | — |
 | 2026-04-20 | **恢复 `dw_base/__init__.py:16` 的 `HADOOP_CONF_DIR` export(反转 2026-04-18 第四轮决策的一小部分)**:`spark-sql-starter.py -f workspace/20260420/select_dim_calendar_dw2.sql` 在新 CDH 环境报 `When running with master 'yarn' either HADOOP_CONF_DIR or YARN_CONF_DIR must be set` —— Spark on YARN 启动时 `SparkSubmitArguments.validateSubmitArguments` 强校验该 env;bigdata 账号 shell 里未 export。2026-04-18 第四轮决策(`kb/92:158`)把这行当"死代码"删,判断只基于 DataX JVM(DataX 确实不靠它,HA 走 ini `[hadoop_config]` 注入),忽略了同一 `dw_base/__init__.py` 也是 Spark 入口的 bootstrap。本次恢复:`os.environ['HADOOP_CONF_DIR'] = '/etc/hadoop/conf'` 加回,注释更新为"Spark 需要;DataX 不读 classpath"。同步更新 `kb/90 §2.8` 末尾"死代码"段(重写为"仅对 Spark 生效")+ §2.8 代码改造清单附表对应行(从"删除"改为"保留",给出双路径理由)。DataX 侧结论(ini `[hadoop_config]` 注入 HA、`HADOOP_CONF_DIR` 对 DataX JVM 无效)不受影响 | — |
 | 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-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 状态改"推进中 / 部分提前完成" | — |