Преглед изворни кода

refactor(dw_base): __init__.py 去 findspark 与 21 个未用颜色常量

tianyu.chu пре 2 недеља
родитељ
комит
709ca3920b
6 измењених фајлова са 15 додато и 71 уклоњено
  1. 0 43
      dw_base/__init__.py
  2. 1 1
      kb/00-项目架构.md
  3. 11 24
      kb/90-重构路线.md
  4. 2 1
      kb/92-重构进度.md
  5. 0 1
      requirements.txt
  6. 1 1
      tests/README.md

+ 0 - 43
dw_base/__init__.py

@@ -6,8 +6,6 @@ import socket
 import sys
 import time
 
-import findspark
-
 from dw_base.utils.env_loader import bootstrap_env
 
 bootstrap_env()
@@ -40,58 +38,19 @@ RELEASE_ROOT_DIR = os.environ['RELEASE_ROOT_DIR']
 
 if not PROJECT_ROOT_PATH.startswith(RELEASE_ROOT_DIR) or USER != RELEASE_USER:
     DO_RESET: str = '\033[0m'
-    CHG_BOLD: str = '\033[1m'
     NORM_RED: str = '\033[0;31m'
     NORM_GRN: str = '\033[0;32m'
     NORM_YEL: str = '\033[0;33m'
-    NORM_BLU: str = '\033[0;34m'
     NORM_MGT: str = '\033[0;35m'
     NORM_CYN: str = '\033[0;36m'
-    NORM_WHT: str = '\033[0;37m'
-
-    BOLD_RED: str = '\033[1;31m'
-    BOLD_GRN: str = '\033[1;32m'
-    BOLD_YEL: str = '\033[1;33m'
-    BOLD_BLU: str = '\033[1;34m'
-    BOLD_MGT: str = '\033[1;35m'
-    BOLD_CYN: str = '\033[1;36m'
-    BOLD_WHT: str = '\033[1;37m'
-
-    BGRD_RED: str = '\033[41m'
-    BGRD_GRN: str = '\033[42m'
-    BGRD_YEL: str = '\033[43m'
-    BGRD_BLU: str = '\033[44m'
-    BGRD_MGT: str = '\033[45m'
-    BGRD_CYN: str = '\033[46m'
-    BGRD_WHT: str = '\033[47m'
 else:
     DO_RESET: str = ''
-    CHG_BOLD: str = ''
     NORM_RED: str = ''
     NORM_GRN: str = ''
     NORM_YEL: str = ''
-    NORM_BLU: str = ''
     NORM_MGT: str = ''
     NORM_CYN: str = ''
-    NORM_WHT: str = ''
-
-    BOLD_RED: str = ''
-    BOLD_GRN: str = ''
-    BOLD_YEL: str = ''
-    BOLD_BLU: str = ''
-    BOLD_MGT: str = ''
-    BOLD_CYN: str = ''
-    BOLD_WHT: str = ''
-
-    BGRD_RED: str = ''
-    BGRD_GRN: str = ''
-    BGRD_YEL: str = ''
-    BGRD_BLU: str = ''
-    BGRD_MGT: str = ''
-    BGRD_CYN: str = ''
-    BGRD_WHT: str = ''
 IS_RUN_BY_RELEASE_USER = False
-IS_RUN_BY_NORMAL_USER = False
 LOG_ROOT_DIR = os.environ['LOG_ROOT_DIR']
 if USER == RELEASE_USER:
     IS_RUN_BY_RELEASE_USER = True
@@ -104,7 +63,6 @@ elif USER == BANNED_USER:
           f'{DO_RESET}')
     exit(ERROR_CODE)
 else:
-    IS_RUN_BY_NORMAL_USER = True
     cow_says()
     print(f'{NORM_CYN}{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} '
           f'{NORM_MGT}Project {NORM_GRN}{PROJECT_NAME} '
@@ -123,4 +81,3 @@ else:
 if not IS_RUN_IN_RELEASE_DIR or USER != RELEASE_USER:
     os.system(f'echo -en "{NORM_GRN}"')
 os.system(f'echo -en "{DO_RESET}"')
-findspark.init()

+ 1 - 1
kb/00-项目架构.md

@@ -32,7 +32,7 @@ poyee-data-warehouse/              # 项目根目录(仓库名 = 部署名)
 │   ├── imports/{yyyymmdd}/        #   一次性入仓(硬盘、历史 dump、外部 CSV),按执行日期归档
 │   └── exports/{yyyymmdd}/        #   一次性出仓任务,按执行日期归档
 ├── dw_base/                       # 通用库层
-│   ├── __init__.py                #   全局初始化(环境检测、findspark、用户/权限判断、颜色常量)
+│   ├── __init__.py                #   全局初始化(环境检测、用户/权限判断、颜色常量)
 │   ├── common/                    #   常量、容器(alerter / config / template 常量)
 │   ├── spark/                     #   SparkSQL 引擎(Session 管理、UDF 注册、SQL 执行、数据导出)
 │   ├── udf/                       #   UDF 库(common 通用 + business 业务专用)

+ 11 - 24
kb/90-重构路线.md

@@ -546,31 +546,18 @@ record_per_channel = 100000
 - 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)]
+## 三、`__init__.py` 瘦身(已完成 · 修剪式) [聚簇 B(B1)]
 
-**现状:** `tendata/__init__.py` 约 120 行,import 即执行以下操作:
-- 环境变量设置
-- 颜色常量定义(30+ 个)
-- findspark.init()
-- 用户/权限/路径检测 + 打印
-- cow_says() 调用 shell
+**2026-04-21 完成形态**:原地修剪,不拆 `core/`。`dw_base/__init__.py` 从 127 行 → 83 行。
 
-**问题:**
-- 任何 `from dw_base import xxx` 都会触发全部初始化
-- 不在 Spark 节点上运行的脚本也被迫执行 `findspark.init()`
-- 影响单元测试(测试 UDF 函数也要初始化 Spark 环境
+**落地动作**:
+- 删 `import findspark` + `findspark.init()`:pip pyspark 已在 venv site-packages 直接覆盖 `import pyspark`,findspark 在 CDH 节点上即便间接反推出 `$SPARK_HOME` 也只是把同版本 parcel pyspark 前插进 sys.path,业务表现零差异(冒烟已确认)
+- 删 21 个外部零引用的颜色常量:`CHG_BOLD` / `NORM_BLU` / `NORM_WHT` / 7×`BOLD_*` / 7×`BGRD_*`(if/else 两分支同步删)
+- 删 `IS_RUN_BY_NORMAL_USER` 状态变量(两处赋值外部均无引用)
 
-**建议拆分为:**
+**未拆分为 `core/env.py` / `core/colors.py` / `core/spark_env.py` 的理由**:findspark 删除后"findspark 按需 import"的懒加载诉求大半消失;剩余颜色/env 检测拆三文件需改 11 处调用点 import,收益比修剪方案差,暂不做。若后续单元测试对 "import dw_base 零副作用" 有刚性需求再拆。
 
-```python
-# dw_base/__init__.py —— 仅做最基本的路径定义
-PROJECT_ROOT_PATH = ...
-PROJECT_NAME = ...
-
-# dw_base/core/env.py —— 环境检测(延迟调用)
-# dw_base/core/colors.py —— 颜色常量
-# dw_base/core/spark_env.py —— findspark 初始化(按需 import)
-```
+**最终 `__init__.py` 保留**:`PROJECT_ROOT_PATH` / `PROJECT_NAME` / `bootstrap_env()` / `sys.path.append` / `HADOOP_CONF_DIR` / `SPARK_CONF_DIR` / `PYSPARK_*` / `COMMON_SPARK_UDF_FILE` / `BANNED_USER` 退出守卫 / `IS_RUN_BY_RELEASE_USER` / `IS_RUN_IN_RELEASE_DIR` / 启动 print / `cow_says()` / 6 个实际被引用的颜色常量(`DO_RESET` / `NORM_RED` / `NORM_GRN` / `NORM_YEL` / `NORM_MGT` / `NORM_CYN`)。
 
 ## 四、代码风格修正(中优先级) [聚簇 B(B3)]
 
@@ -663,7 +650,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 / python-dateutil / wheel / pytest |
 | **无引用(DROP)** | 直接移除 | openvino / transformers / scikit-learn / scipy / numpy / Flask / matplotlib / lxml / SQLAlchemy / jieba / cpca / openpyxl / xlrd / 等 20+ 个 |
 | **stdlib 冗余(STDLIB)** | 移除 backport | `configparser` —— Python 3 标准库自带,backport 安装反而会覆盖 stdlib |
 | **弱依赖(LAZY)** | **不写进 requirements**,用到时手动 pip install | elasticsearch / pyhive / redis / cryptography / oss2 / fuzzywuzzy / pypinyin —— 都只被即将清理的老业务代码引用 |
@@ -672,8 +659,8 @@ tests/
 
 - LAZY 类依赖关联的老代码:`get_oldmongo_*` / `mg2es/` / `ent_interface_dingtalk*` 于 2026-04-20 第一批提前清理;同日第二批清理 `dw_base/oss/` 整目录、`dw_base/scheduler/` 整目录(含 polling_scheduler / drop_partitions / drop_daily_full_snapshot_tbls)、`dw_base/hive/` 整目录、`dw_base/utils/` 7 文件(data_distinct / diff_utils / excel_to_hive_utils / hive_diff_database / hive_to_excel_utils / pdt_check_table\*);剩余 `customs/similarity.py` 等在阶段 4 / 阶段 5 一并清理
 - 不需要 `requirements-base.txt` / `requirements-dev.txt` 分文件——当前依赖规模下单文件已经足够
-- pyspark==2.4.0 固定(对齐 CDH 6.3.2 parcel 自带版本):`pip install` 把 pyspark 装进解释器 site-packages 解决 PyCharm 远程解释器静态索引红线 + 本地 pytest;运行时 `findspark.init()` 指向集群 `$SPARK_HOME/python/`,两条链路同版本不冲突
-- **TODO 评估 `findspark` 移除**:`findspark` 原本解决的是 Spark Python 代码不在 `sys.path` 的问题(HDP 时代常见);CDH + pip 安装的 pyspark 情境下,解释器 site-packages 自带 pyspark 包已能直接 `import pyspark`,再配合 `SPARK_CONF_DIR=/etc/spark/conf`(`01-运行环境.md §4`)完成 spark-env.sh / hive-site.xml 加载,`findspark.init()` 的价值趋近于零。评估时机:当前阶段 1-3 以稳定为先,保留不拆;阶段 5 老残留清理时一并 drop 依赖 + `dw_base/__init__.py:9` 的 import 与 `:127` 的 `findspark.init()` 调用
+- pyspark==2.4.0 固定(对齐 CDH 6.3.2 parcel 自带版本):`pip install` 把 pyspark 装进解释器 site-packages 解决 PyCharm 远程解释器静态索引红线 + 本地 pytest;集群运行时同一解释器的 site-packages pyspark 直接命中,HMS 走 `SPARK_CONF_DIR=/etc/spark/conf/hive-site.xml`(见 `01-运行环境.md §4`)
+- `findspark` 已于 2026-04-21 随 §三 瘦身删除(冒烟确认其在 CDH + pip pyspark 情境下只做同版本同路径覆盖,行为无差异,详见 `92-进度.md` changelog)
 
 ### 7.2 日志改进
 

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

@@ -67,7 +67,7 @@
 - [x] Python 侧由 `dw_base/utils/env_loader.py` 通过 bash 子进程解析注入 `os.environ`(单源,不做双份配置)
 - [ ] 建立 `conf/workers.ini`(DataX Worker 列表 + 权重 map,整体迁出 `bin/common/init.sh:18-31`)
 - [ ] 建立 `conf/alerter.ini`(企微 Webhook,**入库**;格式见 `90-重构路线.md` §2.1)
-- [ ] `dw_base/__init__.py` 瘦身(拆分初始化逻辑,见 `90-重构路线.md` §3)**— 必须先做,下面 spark-defaults 依赖瘦身后的 `PROJECT_ROOT_PATH`**
+- [x] `dw_base/__init__.py` 瘦身(2026-04-21,修剪式,不拆 `core/`;见 `90-重构路线.md` §三 已完成态)
 - [ ] 建立 `conf/spark-defaults.conf`(Spark 全局默认参数,Spark 原生格式,见 `90-重构路线.md` §2.3)
 - [ ] 改造 `dw_base/spark/spark_sql.py`:构造函数 fall back 到 conf;实现 L1(conf) < L2(SQL 内 SET,仅 `spark.sql.*` 系生效) < L3(命令行 -sc / 构造函数传参) 三级覆盖
 - [ ] 验证:同一条 SQL 在无 SET、有 SET、命令行 -sc 三种场景下 `spark.conf.get(...)` 返回值符合优先级预期
@@ -178,3 +178,4 @@
 | 2026-04-21 | **删除 `bin/flume-control.sh`(194 行;事实不可用)**:脚本顶部 shebang 损坏(`ho#!/bin/bash`)+ 依赖已在 2026-04-20 删除的 `bin/wechat-work-alert.sh` + L64 `conf/flume/*.properties` 与 L162 `conf/flume/config/*.properties` 路径自相矛盾,实际已跑不起来。决定:整文件删 + Kafka→HDFS 接入通道的设计理念归档到 kb/90 §5.2 历史档案,按需重建时以该档为参考(不沿用老 `SKB_LITTLE_CUTE` / 手机号硬编码告警,重建时按 `conf/alerter.ini` 外配走) | — |
 | 2026-04-21 | **SQL 风格基线尝试后撤回**:本轮前半段把 `sql_style.xml` 从 `conf/` 挪到项目根,并在 kb/30 §3.2.1 / §3.2.2 立了强基线(关键字/类型 UPPER、SELECT/FROM/ORDER/GROUP 一项一行、JOIN/ON 缩进、CASE/CTE/UNION/OVER/INSERT OVERWRITE/分号九条换行与缩进样例)。实测 IDEA formatter 支持面不足(KEYWORD_CASE 仅作用于新输入不改存量、SELECT 前置逗号长期不支持、ORDER/GROUP 一项一行的 option 名 JetBrains 非公开、UNION 前后空行 formatter 不管、CASE THEN/END 独立行无选项控制),强约束无法靠 formatter 落地。本轮后半段全部回退:删 `sql_style.xml`、kb/30 §3.2.1 / §3.2.2 整节删除、原 §3.2.3 不对齐 AS 重编号为 §3.2.1。团队 SQL 格式化改由各自 IDEA 默认 + 项目 SQL 方言统一设为 Spark 承担,冲突走 review | — |
 | 2026-04-21 | **下线"阶段 3:业务 SQL 从零开发" + 取消 UDF 注释补齐 + kb/31 首批登记 13 个通用 UDF**:(a) 业务 SQL 从零开发属于新开发、不属于重构 scope:kb/92 总览表删阶段 3 行、阶段 3 整节删除、阶段 5 前置条件从"阶段 3 稳定"改为"新业务 SQL 稳定";kb/90 §〇 聚簇表删 E 行、DAG 图删 E 节点、关键依赖边 "A+B+C→E" 与 "E→F" 合并为 "新业务 SQL 生产稳定→F"、§八 聚簇 E 整节删除、当前推进建议"等待前置"里 E 行改为 F 行。(b) 通用 UDF 注释已由开发者手动补完(`spark_common_udf.py` 13 个 `@udf` 函数均带 `UDF-XX` 顺序编号 + 分节注释),kb/90 §2.12 删"5 段模板 + 5 批 commit"规划、"40 函数"更正为"13 个注册 UDF"、标题从"注释完整化 + 自查表"改为"自查表"。(c) `kb/31-UDF手册.md` §1 通用 UDF 表从空壳填入 13 行(UDF-01/02/21/22/23/31/32/33/41/42/51/52/53),分类按代码中分节注释(JSON / ARRAY / STRING / NUMERIC-DATE-HASH / CROSS-TYPE),函数编号按代码中 `UDF-XX` 注释;§2 业务 UDF 保持占位;非 `@udf` 普通 `def`(18 个辅助 / 工具函数)不登记 | — |
+| 2026-04-21 | **聚簇 B.1 `__init__.py` 瘦身(修剪式,不拆 `core/`)**:`dw_base/__init__.py` 从 127 行 → 83 行。三处删除:(a) `import findspark` + `findspark.init()` —— 查证 3 条事实后安全删:findspark 全仓仅此 2 处引用;入口全走 `python3 xxx.py`(非 `spark-submit`),`SPARK_HOME` 从未被代码注入,findspark 在 CDH 节点上 `which spark-submit → readlink -f` 反推出 parcel `$SPARK_HOME` 把 `$SPARK_HOME/python` 前插进 sys.path,但 pip pyspark 2.4.0 和 parcel pyspark 2.4.0 同版本,业务表现零差异(见里程碑 `datax+spark-smoke-2026-04-20` 冒烟链路,HMS 真正入口是 `SPARK_CONF_DIR=/etc/spark/conf/hive-site.xml`,与 findspark 无关);(b) 删 21 个外部零引用的颜色常量 —— `CHG_BOLD` / `NORM_BLU` / `NORM_WHT` / 7×`BOLD_*` / 7×`BGRD_*`(if/else 两分支同步删),保留实际被引用的 6 个(`DO_RESET` / `NORM_RED` / `NORM_GRN` / `NORM_YEL` / `NORM_MGT` / `NORM_CYN`);(c) 删 `IS_RUN_BY_NORMAL_USER` 状态变量(两处赋值外部无引用,仅内部 `elif` 分支走到时为 `True`,无消费者)。**不拆 `core/*` 的理由**:findspark 去掉后"懒加载"诉求大半消失,拆分需改 11 处调用点 import,ROI 低;py/sh 颜色双份是运行时分家的必然(跨 runtime 单源化要加 subprocess 解析,得不偿失),真冗余只是 py 侧定义超过实际被用的部分。联动:`requirements.txt:3` 删 `findspark==2.0.1`;`tests/README.md:26` findspark 段改写为 HMS 入口说明;`kb/00 §1` `__init__.py` 行注释去 findspark;`kb/90 §三` 改写为"已完成 · 修剪式"并附未拆 `core/` 的理由;`kb/90 §7.1` KEEP 行去 findspark + 末尾 TODO 行改写为"已删除" | — |

+ 0 - 1
requirements.txt

@@ -1,6 +1,5 @@
 
 pyspark==2.4.0
-findspark==2.0.1
 
 
 pandas==1.1.5

+ 1 - 1
tests/README.md

@@ -23,7 +23,7 @@
 ## 依赖
 
 - `pytest`(**待加入 `requirements.txt`**)
-- `pyspark==2.4.0`(已在 requirements.txt,`findspark` 运行时定位 CDH 集群,同版本双轨
+- `pyspark==2.4.0`(已在 requirements.txt,版本对齐 CDH 6.3.2 parcel;集群运行时 HMS 通过 `SPARK_CONF_DIR=/etc/spark/conf` 下的 `hive-site.xml` 加载
 - 对 UDF 单测:本地 SparkSession 即可跑,不需要集群
 
 ## 状态