30-开发规范.md 11 KB

开发规范

本文档记录 poyee-data-warehouse 团队通用开发流程与项目管理规范。 与 数仓命名规范.md90-重构路线.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)

目前 TPAD 已创建数据需求工作流技术需求工作流

2.1 TPAD 任务建档要求

耗时 要求
2 小时以下临时需求 需要聊天记录做留档
2 小时以上 必须建立 TPAD 任务
8 小时以上 必须有方案或设计文档

3. 数据开发流程

3.1 数据开发全流程图

flowchart TD
    A[数据需求] --> B[需求沟通]
    B --> C[需求确认]
    C --> D{是否涉及敏感数据?}
    D -->|是| E[敏感数据使用审批]
    E --> F{是否审批通过?}
    F -->|否| Z[结束]
    F -->|是| G{是否需要新的采集方案?}
    D -->|否| G
    G -->|是| H[采集需求流程]
    H --> G
    G -->|否| I{所需指标维度<br/>是否已进仓?}
    I -->|否| J[数据接入流程]
    J --> I
    I -->|是| K[排期开发]
    K --> L[开发完成]
    L --> M[需求方验收]
    M --> N{是否验收通过?}
    N -->|否| K
    N -->|是| O{是否追溯历史数据?}
    O -->|否| Z
    O -->|是| P[追溯数据]
    P --> Q[追溯及验收完成]
    Q --> Z

3.2 关键节点说明

数据开发在通用流程基础上增加以下专属环节:

环节 说明
敏感数据审批 涉及用户身份证、联系方式、支付信息等敏感字段需走专项审批
采集需求流程 数据源尚未接入时,先走 DataX/Kafka 采集接入流程
数据接入流程 数据已采集但尚未建模入仓时,先落 ODS/DWD
指标维度复用判定 先检查所需指标是否已在字典,避免重复建模
数据探查 源数据行数、空值率、主键唯一性、字段分布
建模评审 对照总线矩阵与维度建模五步法(见 数仓分层与建模.md
命名合规自检 对照 数仓命名规范.md 第 7 节 Checklist
口径对齐 对照 指标体系.md 的指标字典
数据质量校验 在 DolphinScheduler 工作流中加入质量校验节点
历史回溯 确保任务支持按 dt 回跑;追溯完成后需要验收

4. 代码开发规范

4.1 Python / PySpark

  • PEP 8 风格
  • 禁用 dict.__contains__(key),改用 key in dict
  • 禁止 SQL 字符串拼接(防 SQL 注入),使用参数化查询
  • 硬编码配置项必须外置到 conf/(见 90-重构路线.md §2)
  • 敏感信息(数据库账密)不得入库

4.2 SQL

  • 表名、字段名遵循五段式命名
  • 所有字段必须带 COMMENT
  • 分区字段统一 dt(日期)/ hr(小时)
  • 存储格式统一 ORC

4.2.1 IDE SQL 格式化配置

conf/sql_style.xmlJetBrains 系 IDE(PyCharm / DataGrip / IntelliJ)的 SQL Code Style 导出文件,团队统一从此文件导入,避免每人格式化后 diff 里一堆空白噪音。

导入方式(PyCharm 为例):

  1. FileSettingsEditorCode StyleSQL
  2. 右上角齿轮图标 → Import SchemeIntelliJ IDEA code style XML
  3. 选择 conf/sql_style.xml → 确认覆盖当前 scheme
  4. 应用后,Ctrl+Alt+L 触发格式化即按此风格

关键风格约定(所有 SQL 方言统一生效):

配置项 说明
KEYWORD_CASE 0 关键字不强制大小写(保留作者原写法)
TYPE_CASE 3 类型名小写
SELECT_EL_WRAP / FROM_EL_WRAP 2 SELECT 字段 / FROM 表每个独占一行
CORTEGE_COMMA_1ST true 逗号前置, col 而不是 col,),减少增删行的 diff 噪音
SELECT_USE_AS_WORD 1 别名写 AS xxx,不省略
SELECT_ALIGN_AS false 不对齐 AS 关键字(见下方说明)
FROM_PLACE_ON / FROM_INDENT_JOIN 10 / false JOIN 换行、不额外缩进
INSERT_INTO_NL 1 / 2 INSERT INTO 换行
EXPR_CASE_END 1 CASE / END 换行
CONTINUATION_INDENT_SIZE 4 续行缩进 4 空格

4.2.2 为什么不对齐 AS

字段别名不对齐 AS 关键字是刻意的,理由:

  1. diff 噪音:对齐 AS 需要按同一 SELECT 内最长字段补空格。任意字段改名会触发整列空格重算,一个字段改动变成 N 行 diff,code review 里真实逻辑变更被空白变更淹没
  2. 与"逗号前置"冲突:逗号前置的动机就是让每一行独立、增删行不污染邻居;对齐 AS 又把"相邻行耦合"引回来了,自相矛盾
  3. git blame 失真:纯空白重排会把一堆行的作者改成最近那次格式化的人
  4. Hive/Spark SQL 字段常很长:数仓里 trd_order_pay_amt_rmb_total_1d 这种 30+ 字符的字段名很常见,对齐后右边要留 40+ 空格,一屏横向放不下反而更难读
  5. 可读性不需要靠对齐:每个字段一行 + 逗号前置已足够清晰

4.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 工作流加质量校验节点
revert 撤销某次提交 revert: feat(raw/crm): ...

约定

  1. 标题 ≤ 50 字符,祈使句(「新增 xxx」而不是「新增了 xxx」)
  2. scope 可选但推荐:数仓项目里 scope 常取 {层}/{域}(如 dwd/trd)或模块名(dw_basebinkbconf
  3. 破坏性变更:标题末尾加 !,正文以 BREAKING CHANGE: 开头说明迁移方式
    • 例:refactor(dw_base)!: 拆分 __init__.py + BREAKING CHANGE: 需要在调用处显式 import findspark
  4. 一次提交做一件事:不要把"新增表 + 顺手修 bug + 改文档"塞一起,按 type 拆成 3 个 commit
  5. 关联 TPAD / issue:正文末尾加 Refs: TPAD-1234Closes: #42

反例(会被 reject):

  • update / 修改 / 提交 —— 没有 type,描述空洞
  • feat: xxx\nfix: yyy\ndocs: zzz —— 一条 commit 混多个 type
  • feat: 新增了一大堆表 —— scope 和具体目标不明

5. 测试规范

90-重构路线.md §6。核心要点:

  • UDF 单测:纯 Python,不依赖 Spark
  • DataX 配置生成单测
  • Spark 集成测试:local[*] 模式
  • 数据质量校验:行数、空值率、主键唯一性

6. manual/ 临时 SQL 规范

manual/ 目录存放一次性、非幂等的 SQL 脚本,与 jobs/ 的语义完全独立。详细目录约定见 00-项目架构.md §8,这里只列开发团队必须遵守的核心规则:

  1. 严禁接入定时调度manual/ 下任何脚本都不得被 DolphinScheduler 定时工作流引用;仅允许通过一次性工作流或命令行手动触发
  2. 命名必须带日期前缀{yyyymmdd}_{层}_{域}_{简述}.sql,便于按时间排序与过期归档
  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 可改
    • 历史数据回刷 → 优先复用 jobs/ 原 SQL + 日期参数,manual/backfill/ 只放调用包装
    • 临时取数给业务方 → manual/adhoc/
    • 脏数据订正 → manual/fix/,必须附 TPAD 工单号
  6. 归档策略:执行完成后保留 3-6 个月作为审计证据,过期后移入 manual/archive/ 或直接删除

7. 相关文档