|
|
@@ -1,77 +1,13 @@
|
|
|
# 开发规范
|
|
|
|
|
|
-> 本文档记录 `poyee-data-warehouse` 团队通用开发流程与项目管理规范。
|
|
|
+> 本文档记录 `poyee-data-warehouse` 数仓数据开发流程与项目管理规范。
|
|
|
> 与 `数仓命名规范.md`、`90-重构路线.md` 配合使用。
|
|
|
|
|
|
-## 1. 通用开发流程
|
|
|
-
|
|
|
-```
|
|
|
-需求评审 → 技术评审 → 开发&测试排期 → 设计文档 → 开发&测试 → 需求方验收 → 生产部署 → 复盘总结
|
|
|
-```
|
|
|
-
|
|
|
-### 1.1 需求评审
|
|
|
-
|
|
|
-详细了解需求背景与细节,讨论可行性。关键点:
|
|
|
-- 需求是否明确?解决什么问题?
|
|
|
-- 复杂度高时能否分阶段实施?
|
|
|
-- 完成的期望指标、验收标准、交付形式?
|
|
|
-- 技术上能否实现、逻辑有无问题?
|
|
|
-- 开发期间遇到问题与谁对接?
|
|
|
-- 需求未明确前必须让需求方澄清疑问点
|
|
|
-- 对接完成后邮件告知
|
|
|
-
|
|
|
-### 1.2 技术评审
|
|
|
-
|
|
|
-阐述详细的技术实现方案,评估合理性:
|
|
|
-- 表结构设计
|
|
|
-- 接口定义
|
|
|
-- 技术难点及应对
|
|
|
-
|
|
|
-### 1.3 开发 & 测试排期
|
|
|
-
|
|
|
-评估工作量,安排各步骤截止日期。
|
|
|
-
|
|
|
-### 1.4 输出开发设计文档
|
|
|
-
|
|
|
-**放置位置**:Confluence(或团队 Wiki)。
|
|
|
-
|
|
|
-**必要章节**:
|
|
|
-- 需求背景
|
|
|
-- 开发设计(技术方案)
|
|
|
-- 排期计划
|
|
|
-- 开发流程详细内容
|
|
|
-- 附录
|
|
|
-
|
|
|
-> **必须在开发测试开始前**完成需求背景、技术方案、排期计划;其他部分可随进度补充。
|
|
|
-
|
|
|
-### 1.5 开发 & 测试
|
|
|
-
|
|
|
-按技术方案和排期实现。
|
|
|
-
|
|
|
-### 1.6 需求方验收
|
|
|
-
|
|
|
-- 开发修 bug
|
|
|
-- 可提前提供部分样例结果做预验收
|
|
|
-
|
|
|
-### 1.7 生产部署
|
|
|
-
|
|
|
-按环境部署(见 `publish.sh`)。
|
|
|
-
|
|
|
-### 1.8 需求复盘总结
|
|
|
-
|
|
|
-复盘问题出在哪里、以后如何规避、有哪些优点可以借鉴。
|
|
|
-
|
|
|
-### 1.9 对接与验收阶段注意事项
|
|
|
-
|
|
|
-- 首版需求已评审的前提下,若出现频繁变更和不确定点,必须明确要求需求方**批量提供变更点**
|
|
|
-- 建议最多一次批量补充;第二批及以上按**需求变更**流程处理
|
|
|
-- 开发要合理评估,避免承接不合理需求
|
|
|
-
|
|
|
-## 2. 项目管理规范(TPAD)
|
|
|
+## 1. 项目管理规范(TPAD)
|
|
|
|
|
|
目前 TPAD 已创建**数据需求工作流**和**技术需求工作流**。
|
|
|
|
|
|
-### 2.1 TPAD 任务建档要求
|
|
|
+### 1.1 TPAD 任务建档要求
|
|
|
|
|
|
| 耗时 | 要求 |
|
|
|
|------|------|
|
|
|
@@ -79,9 +15,9 @@
|
|
|
| **2 小时以上** | 必须建立 TPAD 任务 |
|
|
|
| **8 小时以上** | 必须有方案或设计文档 |
|
|
|
|
|
|
-## 3. 数据开发流程
|
|
|
+## 2. 数据开发流程
|
|
|
|
|
|
-### 3.1 数据开发全流程图
|
|
|
+### 2.1 数据开发全流程图
|
|
|
|
|
|
```mermaid
|
|
|
flowchart TD
|
|
|
@@ -110,9 +46,7 @@ flowchart TD
|
|
|
Q --> Z
|
|
|
```
|
|
|
|
|
|
-### 3.2 关键节点说明
|
|
|
-
|
|
|
-数据开发在通用流程基础上增加以下专属环节:
|
|
|
+### 2.2 关键节点说明
|
|
|
|
|
|
| 环节 | 说明 |
|
|
|
|------|------|
|
|
|
@@ -127,9 +61,9 @@ flowchart TD
|
|
|
| **数据质量校验** | 在 DolphinScheduler 工作流中加入质量校验节点 |
|
|
|
| **历史回溯** | 确保任务支持按 `dt` 回跑;追溯完成后需要验收 |
|
|
|
|
|
|
-## 4. 代码开发规范
|
|
|
+## 3. 代码开发规范
|
|
|
|
|
|
-### 4.1 Python / PySpark
|
|
|
+### 3.1 Python / PySpark
|
|
|
|
|
|
- PEP 8 风格
|
|
|
- 禁用 `dict.__contains__(key)`,改用 `key in dict`
|
|
|
@@ -137,14 +71,14 @@ flowchart TD
|
|
|
- 硬编码配置项必须外置到 `conf/`(见 `90-重构路线.md` §2)
|
|
|
- 敏感信息(数据库账密)**不得入库**
|
|
|
|
|
|
-### 4.2 SQL
|
|
|
+### 3.2 SQL
|
|
|
|
|
|
- 表名、字段名遵循五段式命名
|
|
|
- 所有字段必须带 `COMMENT`
|
|
|
- 分区字段统一 `dt`(日期)/ `hr`(小时)
|
|
|
- 存储格式统一 ORC
|
|
|
|
|
|
-#### 4.2.1 IDE SQL 格式化配置
|
|
|
+#### 3.2.1 IDE SQL 格式化配置
|
|
|
|
|
|
`conf/sql_style.xml` 是 **JetBrains 系 IDE(PyCharm / DataGrip / IntelliJ)的 SQL Code Style 导出文件**,团队统一从此文件导入,避免每人格式化后 diff 里一堆空白噪音。
|
|
|
|
|
|
@@ -170,7 +104,7 @@ flowchart TD
|
|
|
| `EXPR_CASE_END` | 1 | CASE / END 换行 |
|
|
|
| `CONTINUATION_INDENT_SIZE` | 4 | 续行缩进 4 空格 |
|
|
|
|
|
|
-#### 4.2.2 为什么不对齐 AS
|
|
|
+#### 3.2.2 为什么不对齐 AS
|
|
|
|
|
|
字段别名**不对齐** AS 关键字是刻意的,理由:
|
|
|
|
|
|
@@ -181,70 +115,18 @@ flowchart TD
|
|
|
5. **可读性不需要靠对齐**:每个字段一行 + 逗号前置已足够清晰
|
|
|
|
|
|
|
|
|
-### 4.3 Shell
|
|
|
+### 3.3 Shell
|
|
|
|
|
|
- 环境变量统一从 `conf/env.sh` 读取
|
|
|
- 避免在业务脚本中重复环境检测逻辑(统一交给 Python 入口)
|
|
|
|
|
|
-### 4.4 Git 提交信息(Conventional Commits)
|
|
|
-
|
|
|
-每条 commit message 必须以 `<type>: <简短描述>` 开头,type 从下面固定列表里选一个;长说明放正文,与标题空一行。
|
|
|
-
|
|
|
-| type | 用途 | 示例 |
|
|
|
-|------|------|------|
|
|
|
-| `feat` | 新功能 / 新 job / 新表 | `feat(raw/crm): 新增 ods_crm_ent_contact_di` |
|
|
|
-| `fix` | Bug 修复 / 数据订正 | `fix(dwd/trd): 修复订单金额币种换算错误` |
|
|
|
-| `docs` | 只改文档(含 `kb/`、注释、README) | `docs(kb): 更新 21-命名规范.md §3.9 示例` |
|
|
|
-| `refactor` | 不改变外部行为的重构 | `refactor(dw_base): tendata → dw_base 模块改名` |
|
|
|
-| `perf` | 性能优化 | `perf(dws): 拆 tmp 表减少 shuffle` |
|
|
|
-| `test` | 只增/改测试 | `test(udf): 补 safe_cast_decimal 边界用例` |
|
|
|
-| `chore` | 构建、依赖、CI、打包 | `chore: 精简 requirements.txt` |
|
|
|
-| `style` | 空白 / 格式 / import 顺序(不改逻辑) | `style: sql_style.xml 全局格式化` |
|
|
|
-| `build` | 打包脚本 / publish.sh / Dockerfile | `build: publish.sh 支持 -env 参数` |
|
|
|
-| `ci` | DolphinScheduler / GitHub Actions 配置 | `ci: DS 工作流加质量校验节点` |
|
|
|
-| `ops` | 运维类操作(补数、回刷、重跑、人工干预) | `ops(dwd/trd): 补 20260101-20260131 订单分区` |
|
|
|
-| `revert` | 撤销某次提交 | `revert: feat(raw/crm): ...` |
|
|
|
-
|
|
|
-**约定**:
|
|
|
-
|
|
|
-1. **标题 ≤ 50 字符**,祈使句(「新增 xxx」而不是「新增了 xxx」)
|
|
|
-2. **scope 可选但推荐**:数仓项目里 scope 常取 `{层}/{域}`(如 `dwd/trd`)或模块名(`dw_base`、`bin`、`kb`、`conf`)
|
|
|
-3. **破坏性变更**:标题末尾加 `!`,正文以 `BREAKING CHANGE:` 开头说明迁移方式
|
|
|
- - 例:`refactor(dw_base)!: 拆分 __init__.py` + `BREAKING CHANGE: 需要在调用处显式 import findspark`
|
|
|
-4. **一次提交做一件事**:不要把"新增表 + 顺手修 bug + 改文档"塞一起,按 type 拆成 3 个 commit
|
|
|
-5. **关联 TPAD / issue**:正文末尾加 `Refs: TPAD-1234` 或 `Closes: #42`
|
|
|
-
|
|
|
-**反例**(会被 reject):
|
|
|
-
|
|
|
-- `update` / `修改` / `提交` —— 没有 type,描述空洞
|
|
|
-- `feat: xxx\nfix: yyy\ndocs: zzz` —— 一条 commit 混多个 type
|
|
|
-- `feat: 新增了一大堆表` —— scope 和具体目标不明
|
|
|
-
|
|
|
-### 4.5 占位模块规范
|
|
|
-
|
|
|
-新建 `dw_base/<module>/` 子目录(或 `tests/` 下子目录)时,即使本批**不写实现代码**,也必须带 `README.md`。避免"空 `__init__.py` + 无说明"的幽灵模块堆积(曾于 2026-04-20 清理 `ml/elasticsearch/flink/validation` 四个空壳)。
|
|
|
-
|
|
|
-**README.md 必含 4 节**:
|
|
|
-
|
|
|
-1. **职责** —— 一句话说清该模块做什么 / 不做什么(划边界,与相邻模块的区分)
|
|
|
-2. **对外接口概要** —— 规划中的公开 API(3-5 条 function/class 签名即可,不必最终稿;允许后续漂移)
|
|
|
-3. **依赖** —— 依赖的外部库 + 项目内模块 + 配置文件来源(含账密走 `datasource/` 的说明)
|
|
|
-4. **状态** —— `未启动 / 骨架 / 开发中 / 已交付`,以及当前 blocker 或待确认项
|
|
|
-
|
|
|
-**检查**:
|
|
|
-
|
|
|
-- 下次清理 round,只有空 `__init__.py` 且无 README 的目录 → 直接删(反模式判定)
|
|
|
-- README 与实际代码不符(接口漂移 / 状态陈旧 / 依赖过时)→ 开发者在本轮改动中顺手维护
|
|
|
-
|
|
|
-**示例参考**:`dw_base/io/README.md`、`dw_base/pm/README.md`、`dw_base/dq/README.md`、`dw_base/sync/README.md`、`dw_base/ops/README.md`、`tests/README.md`。
|
|
|
-
|
|
|
-### 4.6 Git 协作规范
|
|
|
+### 3.4 Git 协作规范
|
|
|
|
|
|
本节定义数仓项目团队使用 Git 协作的分支模型与工作流程,保证主干历史整洁可追溯,降低多人协作冲突风险。
|
|
|
|
|
|
-#### 4.6.1 分支模型
|
|
|
+#### 3.4.1 分支模型
|
|
|
|
|
|
-##### 4.6.1.1 分支总览
|
|
|
+##### 3.4.1.1 分支总览
|
|
|
|
|
|
| 分支 | 定位 | 受保护 | 合并来源 | 触发动作 |
|
|
|
|------|------|--------|----------|----------|
|
|
|
@@ -253,7 +135,7 @@ flowchart TD
|
|
|
| `feature` | 公共开发分支 | 是 | `feature-xxx`(个人分支) | 测试通过后合入 `release` |
|
|
|
| `feature-xxx` | 个人开发分支 | 否 | —— | 通过 PR 合入 `feature` 后自动删除 |
|
|
|
|
|
|
-##### 4.6.1.2 分支结构
|
|
|
+##### 3.4.1.2 分支结构
|
|
|
|
|
|
```
|
|
|
[tag: datax+spark-smoke-2026-04-20]
|
|
|
@@ -275,11 +157,11 @@ flowchart TD
|
|
|
└─────────── feature-zhangsan-ods-usr-20260420 ✗ (PR 合入后自动删除)
|
|
|
```
|
|
|
|
|
|
-##### 4.6.1.3 保护策略
|
|
|
+##### 3.4.1.3 保护策略
|
|
|
|
|
|
`master`、`release`、`feature` 三个分支在仓库层面禁用远程推送,所有变更必须通过 PR(Pull Request / Merge Request)流转,仅允许管理员通过合并操作更新。
|
|
|
|
|
|
-#### 4.6.2 代码流转路径
|
|
|
+#### 3.4.2 代码流转路径
|
|
|
|
|
|
```mermaid
|
|
|
flowchart LR
|
|
|
@@ -290,7 +172,7 @@ flowchart LR
|
|
|
|
|
|
代码单向汇聚到 `master`,各合并节点由管理员操作,`release` → `master` 的合并提交需打 Tag。
|
|
|
|
|
|
-#### 4.6.3 开发者工作流
|
|
|
+#### 3.4.3 开发者工作流
|
|
|
|
|
|
```mermaid
|
|
|
sequenceDiagram
|
|
|
@@ -338,17 +220,17 @@ sequenceDiagram
|
|
|
|
|
|
日常通过 PyCharm 的 Git 面板与仓库网页端完成上述操作即可。
|
|
|
|
|
|
-#### 4.6.4 要求使用 Rebase 而非 Merge
|
|
|
+#### 3.4.4 要求使用 Rebase 而非 Merge
|
|
|
|
|
|
- **历史线性整洁**:没有冗余的 merge 提交,可视化合并树清晰
|
|
|
- **二分查找友好**:`git bisect` 定位问题提交更精准
|
|
|
- **Review 聚焦**:PR 里只有本次任务的提交,Reviewer 不会看到与本次无关的 merge commit
|
|
|
|
|
|
-#### 4.6.5 Hotfix 紧急修复流程
|
|
|
+#### 3.4.5 Hotfix 紧急修复流程
|
|
|
|
|
|
线上 `release` 分支出现紧急故障时,走独立的 hotfix 流程,避免等待 `feature` 中未完成功能的流转。
|
|
|
|
|
|
-##### 4.6.5.1 流转路径
|
|
|
+##### 3.4.5.1 流转路径
|
|
|
|
|
|
```mermaid
|
|
|
flowchart LR
|
|
|
@@ -362,7 +244,7 @@ flowchart LR
|
|
|
|
|
|
> 为什么不是 `release` 合入 `feature`?`release` 本身由大量 merge commit 构成,反向合入会污染 `feature` 的线性历史。用 hotfix 分支发两个 PR,两边拿到的都是同一个独立的修复提交。
|
|
|
|
|
|
-##### 4.6.5.2 操作步骤
|
|
|
+##### 3.4.5.2 操作步骤
|
|
|
|
|
|
1. 开发者基于最新 `origin/release` 创建 `hotfix-xxx` 分支,**只做 bug 修复,不夹带其他改动**
|
|
|
2. 提 PR #1 至 `release`,管理员 Review 通过后合入,**暂不删除 hotfix 分支**
|
|
|
@@ -371,15 +253,15 @@ flowchart LR
|
|
|
5. 管理员 Review 通过后合入 `feature`,删除 hotfix 分支
|
|
|
6. 管理员将 `release` 合入 `master` 并打 hotfix tag
|
|
|
|
|
|
-##### 4.6.5.3 冲突异常处理
|
|
|
+##### 3.4.5.3 冲突异常处理
|
|
|
|
|
|
正常情况下 PR #2 不应产生冲突——hotfix 职责单一,`feature` 上不应存在针对同一代码的并行修改。
|
|
|
|
|
|
**若产生冲突,说明 `feature` 上有人改动了 hotfix 修复的同一区域**。此时**不要自行解决冲突**,否则会出现 `release` 与 `feature` 修复版本不一致,后续发布可能导致 bug 复现。正确做法:暂停合并,由管理员召集 hotfix 作者与 `feature` 侧的改动者协调,确认最终版本后再继续。
|
|
|
|
|
|
-#### 4.6.6 分支 / Tag 命名
|
|
|
+#### 3.4.6 分支 / Tag 命名
|
|
|
|
|
|
-##### 4.6.6.1 个人分支命名
|
|
|
+##### 3.4.6.1 个人分支命名
|
|
|
|
|
|
格式:`feature-<姓名拼音>-<描述>-<日期>`
|
|
|
|
|
|
@@ -389,7 +271,7 @@ flowchart LR
|
|
|
| `feature-wangwu-dim-shp-20260419` | 王五开发商品维度,2026-04-19 建分支 |
|
|
|
| `feature-zhangsan-ods-usr-20260420` | 张三开发用户域 ODS 层,2026-04-20 建分支 |
|
|
|
|
|
|
-##### 4.6.6.2 Hotfix 分支命名
|
|
|
+##### 3.4.6.2 Hotfix 分支命名
|
|
|
|
|
|
格式:`hotfix-<姓名拼音>-<故障简述>-<日期>`
|
|
|
|
|
|
@@ -399,7 +281,7 @@ flowchart LR
|
|
|
| `hotfix-lisi-ads-prd-null-20260422` | 修复产品宽表空值异常 |
|
|
|
| `hotfix-wangwu-dws-mkt-stale-20260423` | 修复营销宽表数据滞后 |
|
|
|
|
|
|
-##### 4.6.6.3 Tag 命名
|
|
|
+##### 3.4.6.3 Tag 命名
|
|
|
|
|
|
格式:`<描述>-<类型>-<日期>`
|
|
|
|
|
|
@@ -414,7 +296,41 @@ flowchart LR
|
|
|
- 阶段类型:`smoke`(冒烟通过)、`hotfix`(紧急修复)
|
|
|
- Tag 打在 `release` → `master` 的合并提交上,由管理员操作
|
|
|
|
|
|
-## 5. 测试规范
|
|
|
+#### 3.4.7 Commit 信息(Conventional Commits)
|
|
|
+
|
|
|
+每条 commit message 必须以 `<type>: <简短描述>` 开头,type 从下面固定列表里选一个;长说明放正文,与标题空一行。
|
|
|
+
|
|
|
+| type | 用途 | 示例 |
|
|
|
+|------|------|------|
|
|
|
+| `feat` | 新功能 / 新 job / 新表 | `feat(raw/crm): 新增 ods_crm_ent_contact_di` |
|
|
|
+| `fix` | Bug 修复 / 数据订正 | `fix(dwd/trd): 修复订单金额币种换算错误` |
|
|
|
+| `docs` | 只改文档(含 `kb/`、注释、README) | `docs(kb): 更新 21-命名规范.md §3.9 示例` |
|
|
|
+| `refactor` | 不改变外部行为的重构 | `refactor(dw_base): tendata → dw_base 模块改名` |
|
|
|
+| `perf` | 性能优化 | `perf(dws): 拆 tmp 表减少 shuffle` |
|
|
|
+| `test` | 只增/改测试 | `test(udf): 补 safe_cast_decimal 边界用例` |
|
|
|
+| `chore` | 构建、依赖、CI、打包 | `chore: 精简 requirements.txt` |
|
|
|
+| `style` | 空白 / 格式 / import 顺序(不改逻辑) | `style: sql_style.xml 全局格式化` |
|
|
|
+| `build` | 打包脚本 / publish.sh / Dockerfile | `build: publish.sh 支持 -env 参数` |
|
|
|
+| `ci` | DolphinScheduler / GitHub Actions 配置 | `ci: DS 工作流加质量校验节点` |
|
|
|
+| `ops` | 运维类操作(补数、回刷、重跑、人工干预) | `ops(dwd/trd): 补 20260101-20260131 订单分区` |
|
|
|
+| `revert` | 撤销某次提交 | `revert: feat(raw/crm): ...` |
|
|
|
+
|
|
|
+**约定**:
|
|
|
+
|
|
|
+1. **标题 ≤ 50 字符**,祈使句(「新增 xxx」而不是「新增了 xxx」)
|
|
|
+2. **scope 可选但推荐**:数仓项目里 scope 常取 `{层}/{域}`(如 `dwd/trd`)或模块名(`dw_base`、`bin`、`kb`、`conf`)
|
|
|
+3. **破坏性变更**:标题末尾加 `!`,正文以 `BREAKING CHANGE:` 开头说明迁移方式
|
|
|
+ - 例:`refactor(dw_base)!: 拆分 __init__.py` + `BREAKING CHANGE: 需要在调用处显式 import findspark`
|
|
|
+4. **一次提交做一件事**:不要把"新增表 + 顺手修 bug + 改文档"塞一起,按 type 拆成 3 个 commit
|
|
|
+5. **关联 TPAD / issue**:正文末尾加 `Refs: TPAD-1234` 或 `Closes: #42`
|
|
|
+
|
|
|
+**反例**(会被 reject):
|
|
|
+
|
|
|
+- `update` / `修改` / `提交` —— 没有 type,描述空洞
|
|
|
+- `feat: xxx\nfix: yyy\ndocs: zzz` —— 一条 commit 混多个 type
|
|
|
+- `feat: 新增了一大堆表` —— scope 和具体目标不明
|
|
|
+
|
|
|
+## 4. 测试规范
|
|
|
|
|
|
见 `90-重构路线.md` §6。核心要点:
|
|
|
- UDF 单测:纯 Python,不依赖 Spark
|
|
|
@@ -422,7 +338,7 @@ flowchart LR
|
|
|
- Spark 集成测试:`local[*]` 模式
|
|
|
- 数据质量校验:行数、空值率、主键唯一性
|
|
|
|
|
|
-## 6. manual/ 临时 SQL 规范
|
|
|
+## 5. manual/ 临时 SQL 规范
|
|
|
|
|
|
`manual/` 目录存放**一次性、非幂等**的 SQL 脚本,与 `jobs/` 的语义完全独立。详细目录约定见 `00-项目架构.md` §8,这里只列开发团队必须遵守的核心规则:
|
|
|
|
|
|
@@ -437,7 +353,7 @@ flowchart LR
|
|
|
- 脏数据订正 → `manual/fix/`,必须附 TPAD 工单号
|
|
|
6. **归档策略**:执行完成后保留 3-6 个月作为审计证据,过期后移入 `manual/archive/` 或直接删除
|
|
|
|
|
|
-## 7. 相关文档
|
|
|
+## 6. 相关文档
|
|
|
|
|
|
- [命名规范](21-命名规范.md)
|
|
|
- [数仓分层与建模](20-数仓分层与建模.md)
|