整理项目
This commit is contained in:
315
README_FULL.md
315
README_FULL.md
@@ -1,281 +1,216 @@
|
||||
# 飞球 ETL 系统(ODS → DWD)合并版
|
||||
# 飞球 ETL 系统(ODS → DWD)— 详细版
|
||||
|
||||
> 本文在不改变现有用法的前提下,整合了两份历史说明的有效信息;所有冲突以当前仓库中的 `README.md` 为准,补充了架构、测试、迁移、ODS 任务指引、表映射与 DWD 建模原则等内容。
|
||||
> 本文为项目的详细说明,保持与当前代码一致,覆盖 ODS 任务、DWD 装载、质检及开发扩展要点。
|
||||
|
||||
---
|
||||
|
||||
## 1. 项目概述
|
||||
## 1. 项目概览
|
||||
|
||||
面向门店业务的数据工程项目:从上游业务 API 或本地离线 JSON 拉取原始数据,先落地 **ODS**,再清洗装载 **DWD**(含 SCD2 维度历史与事实增量),并提供数据质量校验报表。项目采用模块化、分层架构(配置、API、数据库、加载器/SCD/质量、编排、任务、CLI、测试),统一通过 CLI 调度执行。
|
||||
面向门店业务的 ETL:从上游 API 或离线 JSON 采集订单、支付、会员、库存等数据,先落地 **ODS**,再清洗装载 **DWD**(含 SCD2 维度、事实增量),并输出质量校验报表。项目采用模块化/分层架构(配置、API、数据库、Loader/SCD、质量、调度、CLI、测试),统一通过 CLI 调度。
|
||||
|
||||
---
|
||||
|
||||
## 2. 快速运行(离线示例 JSON)
|
||||
## 2. 快速开始(离线示例 JSON)
|
||||
|
||||
**环境要求:** Python 3.10+、PostgreSQL 可用;`.env` 中关键项:
|
||||
|
||||
- `PG_DSN=postgresql://local-Python:Neo-local-1991125@100.64.0.4:5432/LLZQ-test`
|
||||
**环境要求**:Python 3.10+;PostgreSQL;`.env` 关键项:
|
||||
- `PG_DSN=postgresql://local-Python:Neo-local-1991125@100.64.0.4:5432/LLZQ-test`
|
||||
- `INGEST_SOURCE_DIR=C:\dev\LLTQ\export\test-json-doc`
|
||||
|
||||
**安装依赖:**
|
||||
|
||||
**安装依赖**:
|
||||
```bash
|
||||
cd etl_billiards
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
**一键 ODS→DWD→质量校验(离线回放):**
|
||||
|
||||
**一键 ODS → DWD → 质检(离线回放)**:
|
||||
```bash
|
||||
# 初始化 ODS + DWD
|
||||
python -m etl_billiards.cli.main --tasks INIT_ODS_SCHEMA,INIT_DWD_SCHEMA --pipeline-flow INGEST_ONLY
|
||||
|
||||
# 灌入示例 JSON 到 ODS(可用 .env 中的 INGEST_SOURCE_DIR 覆盖)
|
||||
# 灌入示例 JSON 到 ODS(可用 .env 的 INGEST_SOURCE_DIR 覆盖)
|
||||
python -m etl_billiards.cli.main --tasks MANUAL_INGEST --pipeline-flow INGEST_ONLY --ingest-source "C:\dev\LLTQ\export\test-json-doc"
|
||||
|
||||
# 从 ODS 装载到 DWD
|
||||
# 从 ODS 装载 DWD
|
||||
python -m etl_billiards.cli.main --tasks DWD_LOAD_FROM_ODS --pipeline-flow INGEST_ONLY
|
||||
|
||||
# 质量校验报表
|
||||
python -m etl_billiards.cli.main --tasks DWD_QUALITY_CHECK --pipeline-flow INGEST_ONLY
|
||||
|
||||
# 报表输出:etl_billiards/reports/dwd_quality_report.json
|
||||
```
|
||||
|
||||
> 可按需单独运行:
|
||||
>
|
||||
> 可按需单独运行:
|
||||
> - 仅建表:`python -m etl_billiards.cli.main --tasks INIT_ODS_SCHEMA`
|
||||
> - 仅 ODS 灌入:`python -m etl_billiards.cli.main --tasks MANUAL_INGEST`
|
||||
> - 仅 DWD 装载:`python -m etl_billiards.cli.main --tasks INIT_DWD_SCHEMA,DWD_LOAD_FROM_ODS`
|
||||
|
||||
---
|
||||
|
||||
## 3. 配置与目录约定
|
||||
|
||||
- 示例数据目录:`C:\dev\LLTQ\export\test-json-doc`(可通过 `.env` 的 `INGEST_SOURCE_DIR` 覆盖)。
|
||||
- 日志/导出目录:`LOG_ROOT`、`EXPORT_ROOT` 见 `.env`。
|
||||
- 质量报表:`etl_billiards/reports/dwd_quality_report.json`。
|
||||
- ODS/DWD DDL:`etl_billiards/database/schema_ODS_doc.sql`、`etl_billiards/database/schema_dwd_doc.sql`。
|
||||
## 3. 配置与路径
|
||||
- 示例数据目录:`C:\dev\LLTQ\export\test-json-doc`(可由 `.env` 的 `INGEST_SOURCE_DIR` 覆盖)。
|
||||
- 日志/导出目录:`LOG_ROOT`、`EXPORT_ROOT` 见 `.env`。
|
||||
- 报表:`etl_billiards/reports/dwd_quality_report.json`。
|
||||
- DDL:`etl_billiards/database/schema_ODS_doc.sql`、`etl_billiards/database/schema_dwd_doc.sql`。
|
||||
- 任务注册:`etl_billiards/orchestration/task_registry.py`(默认启用 INIT_ODS_SCHEMA、MANUAL_INGEST、INIT_DWD_SCHEMA、DWD_LOAD_FROM_ODS、DWD_QUALITY_CHECK)。
|
||||
|
||||
**安全提示:** 建议将数据库口令仅保存在 `.env` 或密钥管理平台,避免在示例或脚本中硬编码;生产环境请使用具有最小权限的数据库账号。
|
||||
**安全提示**:建议将数据库凭证保存在 `.env` 或受控秘钥管理中,生产环境使用最小权限账号。
|
||||
|
||||
---
|
||||
|
||||
## 4. 目录结构与主要文件(精要)
|
||||
|
||||
- 根目录:`etl_billiards/` 主代码;`requirements.txt` 依赖;`run_etl.sh/.bat` 启动脚本;`.env/.env.example` 配置;`tmp/` 放置草稿/备份。
|
||||
- `config/`:`defaults.py` 默认值,`env_parser.py` 解析 `.env`,`settings.py` 统一配置加载。
|
||||
- `api/`:`client.py` HTTP 请求、重试与分页。
|
||||
- `database/`:`connection.py` 连接封装,`operations.py` 批量 upsert,DDL SQL。
|
||||
- `tasks/`:业务任务(见第 9 章与第 10 章)。
|
||||
- `loaders/`:ODS/DWD/SCD2 Loader 实现。
|
||||
- `scd/`:`scd2_handler.py` 处理维度 SCD2 历史。
|
||||
- `quality/`:质量检查器(行数/金额对照等)。
|
||||
- `orchestration/`:`scheduler.py` 调度;`task_registry.py` 注册;`run_tracker.py` 运行记录;`cursor_manager.py` 增量游标。
|
||||
- `docs/`:映射与示例文档。
|
||||
- `reports/`:质检输出(如 `dwd_quality_report.json`)。
|
||||
- `tests/`:单元/集成测试;`utils/`:通用工具。
|
||||
## 4. 目录结构与关键文件
|
||||
- 根目录:`etl_billiards/` 主代码;`requirements.txt` 依赖;`run_etl.sh/.bat` 启动脚本;`.env/.env.example` 配置;`tmp/` 草稿/调试归档。
|
||||
- `config/`:`defaults.py` 默认值,`env_parser.py` 解析 .env,`settings.py` AppConfig 统一加载。
|
||||
- `api/`:`client.py` HTTP 请求、重试、分页。
|
||||
- `database/`:`connection.py` 连接封装;`operations.py` 批量 upsert;DDL SQL(ODS/DWD)。
|
||||
- `tasks/`:
|
||||
- `init_schema_task.py`(INIT_ODS_SCHEMA/INIT_DWD_SCHEMA);
|
||||
- `manual_ingest_task.py`(示例 JSON → ODS);
|
||||
- `dwd_load_task.py`(ODS → DWD 映射、SCD2/事实增量);
|
||||
- 其他任务按需扩展。
|
||||
- `loaders/`:ODS/DWD/SCD2 Loader 实现。
|
||||
- `scd/`:`scd2_handler.py` 处理维度 SCD2 历史。
|
||||
- `quality/`:质量检查器(行数/金额对照)。
|
||||
- `orchestration/`:`scheduler.py` 调度;`task_registry.py` 注册;`run_tracker.py` 运行记录;`cursor_manager.py` 水位管理。
|
||||
- `scripts/`:重建/测试/探活工具。
|
||||
- `docs/`:`ods_to_dwd_mapping.md` 映射说明;`ods_sample_json.md` 示例 JSON 说明;`dwd_quality_check.md` 质检说明。
|
||||
- `reports/`:质检输出(如 `dwd_quality_report.json`)。
|
||||
- `tests/`:单元/集成测试;`utils/`:通用工具;`backups/`:备份(若存在)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 架构与流程
|
||||
执行链路(控制流):
|
||||
1) CLI(`cli/main.py`)解析参数 → 生成 AppConfig → 初始化日志/DB 连接;
|
||||
2) 调度层(`scheduler.py`)按 `task_registry.py` 中的注册表实例化任务,设置 run_uuid、cursor(水位)、上下文;
|
||||
3) 任务基类模板:
|
||||
- 获取时间窗口/水位(cursor_manager);
|
||||
- 拉取数据:在线模式调用 `api/client.py` 支持分页、重试;离线模式直接读取 JSON 文件;
|
||||
- 解析与校验:类型转换、必填校验(如任务内部 parse/validate);
|
||||
- 加载:调用 Loader(`loaders/`)执行批量 Upsert/SCD2/增量写入(底层用 `database/operations.py`);
|
||||
- 质量检查(如需):质量模块对行数/金额等进行对比;
|
||||
- 更新水位与运行记录(`run_tracker.py`),提交/回滚事务。
|
||||
|
||||
```
|
||||
CLI (etl_billiards/cli/main.py)
|
||||
↓
|
||||
Orchestration (scheduler / task_registry / run_tracker / cursor_manager)
|
||||
↓
|
||||
Tasks (orders/payments/members/…)
|
||||
↙ ↓ ↘
|
||||
Loaders SCD2 Quality
|
||||
↓
|
||||
Models
|
||||
↓
|
||||
API
|
||||
↓
|
||||
Database
|
||||
↓
|
||||
Config
|
||||
```
|
||||
|
||||
**执行模板(任务层):** 统一模板方法包含:读取增量窗口 → 拉取数据(支持分页/重试)→ 解析与校验 → Loader 写库(Upsert/SCD2)→ 质量检查 → 更新游标与运行记录。
|
||||
数据流与依赖:
|
||||
- 配置:`config/defaults.py` + `.env` + CLI 参数叠加,形成 AppConfig。
|
||||
- API 访问:`api/client.py` 支撑分页/重试;离线 ingest 直接读文件。
|
||||
- DB 访问:`database/connection.py` 提供连接上下文;`operations.py` 负责批量 upsert/分页写入。
|
||||
- ODS:`manual_ingest_task.py` 读取 JSON → ODS 表(保留 payload/来源/时间戳)。
|
||||
- DWD:`dwd_load_task.py` 依据 `TABLE_MAP/FACT_MAPPINGS` 从 ODS 选取字段;维度走 SCD2(`scd/scd2_handler.py`),事实走增量;支持字段表达式(JSON->>、CAST)。
|
||||
- 质检:`quality` 模块或相关任务对 ODS/DWD 行数、金额等进行比对,输出 `reports/`。
|
||||
|
||||
---
|
||||
|
||||
## 6. ODS → DWD 双阶段策略
|
||||
|
||||
为支持回溯/重放与稳定建模,项目采用双阶段:
|
||||
|
||||
1. **ODS 落地**:将原始记录(含分页/抓取时间/来源)按表落地到 `billiards_ods.*`,保留源主键与 payload 以保证可追溯。
|
||||
2. **DWD 清洗**:从 ODS 读取 payload,进行解析、标准化与 SCD2 处理,写入 `billiards.*` 的维度/事实表;事实表走时间/水位增量。
|
||||
## 6. ODS → DWD 策略
|
||||
1. ODS 留底:保留源主键、payload、时间/来源信息。
|
||||
2. DWD 清洗:维度 SCD2,事实按时间/水位增量;字段类型、单位、枚举标准化,保留可溯源字段。
|
||||
3. 业务键统一:site_id、member_id、table_id、order_settle_id、order_trade_no 等统一命名。
|
||||
4. 不过度汇总:DWD 只做明细/轻度清洗,汇总留待 DWS/报表。
|
||||
5. 去嵌套:数组展开为子表/子行,重复 profile 提炼为维度。
|
||||
6. 长期演进:优先加列/加表,避免频繁改已有表结构。
|
||||
|
||||
---
|
||||
|
||||
## 7. 常用命令(CLI)
|
||||
|
||||
## 7. 常用 CLI
|
||||
```bash
|
||||
# 运行全部已注册任务(按 task_registry)
|
||||
# 运行所有已注册任务
|
||||
python -m etl_billiards.cli.main
|
||||
|
||||
# 仅运行指定任务
|
||||
python -m etl_billiards.cli.main --tasks ORDERS,PAYMENTS,MEMBERS
|
||||
|
||||
# 覆盖数据库 DSN
|
||||
# 运行指定任务
|
||||
python -m etl_billiards.cli.main --tasks INIT_ODS_SCHEMA,MANUAL_INGEST
|
||||
# 覆盖 DSN
|
||||
python -m etl_billiards.cli.main --pg-dsn "postgresql://user:pwd@host:5432/db"
|
||||
|
||||
# 覆盖上游 API 端点
|
||||
# 覆盖 API
|
||||
python -m etl_billiards.cli.main --api-base "https://api.example.com" --api-token "..."
|
||||
|
||||
# 试运行(不写库)
|
||||
python -m etl_billiards.cli.main --dry-run --tasks ORDERS
|
||||
python -m etl_billiards.cli.main --dry-run --tasks DWD_LOAD_FROM_ODS
|
||||
```
|
||||
|
||||
> 实际启用的任务代码与管道以当前 `task_registry.py` 与数据库任务配置为准。
|
||||
|
||||
---
|
||||
|
||||
## 8. 测试(ONLINE / OFFLINE)
|
||||
|
||||
- `TEST_MODE=ONLINE`:模拟实时 API,完整 E/T/L。
|
||||
- `TEST_MODE=OFFLINE`:从 `TEST_JSON_ARCHIVE_DIR` 指定的归档 JSON 读取,仅做 Transform + Load(适合回放)。
|
||||
- `TEST_DB_DSN`:如设置,则集成测试连接真实测试库执行写库;未设置则用内存伪库。
|
||||
|
||||
**示例:**
|
||||
|
||||
- `TEST_MODE=ONLINE`:调用真实 API,全链路 E/T/L。
|
||||
- `TEST_MODE=OFFLINE`:从 `TEST_JSON_ARCHIVE_DIR` 读取离线 JSON,只做 Transform + Load。
|
||||
- `TEST_DB_DSN`:如设置,则集成测试连真库;未设置用内存/临时库。
|
||||
示例:
|
||||
```bash
|
||||
# 在线模式覆盖任务
|
||||
TEST_MODE=ONLINE pytest tests/unit/test_etl_tasks_online.py
|
||||
|
||||
# 离线模式回放归档 JSON
|
||||
TEST_MODE=OFFLINE TEST_JSON_ARCHIVE_DIR=tests/source-data-doc pytest tests/unit/test_etl_tasks_offline.py
|
||||
|
||||
# 脚本化组合
|
||||
python scripts/run_tests.py --suite offline --mode OFFLINE --db-dsn postgresql://user:pwd@localhost:5432/testdb
|
||||
python scripts/run_tests.py --preset offline_realdb
|
||||
```
|
||||
|
||||
**数据库连通性检查:**
|
||||
|
||||
```bash
|
||||
python scripts/test_db_connection.py --dsn postgresql://user:pwd@host:5432/db --query "SELECT 1"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 开发与扩展指南
|
||||
|
||||
**添加新任务:**
|
||||
|
||||
```python
|
||||
from tasks.base_task import BaseTask
|
||||
|
||||
class MyTask(BaseTask):
|
||||
def get_task_code(self) -> str:
|
||||
return "MY_TASK"
|
||||
|
||||
def execute(self) -> dict:
|
||||
window_start, window_end, _ = self._get_time_window()
|
||||
records, _ = self.api.get_paginated(...)
|
||||
parsed = [self._parse(r) for r in records]
|
||||
loader = MyLoader(self.db)
|
||||
inserted, updated, _ = loader.upsert(parsed)
|
||||
self.db.commit()
|
||||
return self._build_result("SUCCESS", {"inserted": inserted, "updated": updated})
|
||||
```
|
||||
|
||||
在 `orchestration/task_registry.py` 注册:
|
||||
|
||||
```python
|
||||
from tasks.my_task import MyTask
|
||||
|
||||
default_registry.register("MY_TASK", MyTask)
|
||||
```
|
||||
|
||||
**添加新 Loader / Checker:** 参见 `loaders/`、`quality/` 模块,优先复用批量 upsert 与返回写入统计的统一接口。
|
||||
## 9. 开发与扩展
|
||||
- 新任务:在 `tasks/` 继承 BaseTask,实现 `get_task_code/execute`,并在 `orchestration/task_registry.py` 注册。
|
||||
- 新 Loader/Checker:参考 `loaders/`、`quality/` 复用批量 upsert/质检接口。
|
||||
- 配置:`config/defaults.py` + `.env` + CLI 叠加,新增配置需在 defaults 与 env_parser 中声明。
|
||||
|
||||
---
|
||||
|
||||
## 10. ODS 任务上线指引(摘要)
|
||||
|
||||
- 任务注册脚本:`etl_billiards/database/seed_ods_tasks.sql`,将其中 `store_id` 替换为实际值后执行:
|
||||
|
||||
```bash
|
||||
psql "$PG_DSN" -f etl_billiards/database/seed_ods_tasks.sql
|
||||
```
|
||||
|
||||
- 调度:确认 `etl_admin.etl_task` 中已启用所需 ODS 任务(任务代码见 seed 脚本)。
|
||||
- 离线回灌:开发环境可用 `rebuild_ods_from_json` 初始化 ODS(生产慎用)。
|
||||
- 测试:`pytest etl_billiards/tests/unit/test_ods_tasks.py` 覆盖核心 ODS 任务。
|
||||
## 10. ODS 任务上线指引
|
||||
- 任务注册脚本:`etl_billiards/database/seed_ods_tasks.sql`(替换 store_id 后执行:`psql "$PG_DSN" -f ...`)。
|
||||
- 确认 `etl_admin.etl_task` 中已启用所需 ODS 任务。
|
||||
- 离线回放:可用 `scripts/rebuild_ods_from_json`(如有)从本地 JSON 重建 ODS。
|
||||
- 单测:`pytest etl_billiards/tests/unit/test_ods_tasks.py`。
|
||||
|
||||
---
|
||||
|
||||
## 11. ODS 表映射总览(节选)
|
||||
## 11. ODS 表概览(数据路径)
|
||||
|
||||
| ODS 表名 | 接口 Path | 数据列表路径 |
|
||||
| ------------------------------------ | ---------------------------------------------------- | ----------------------------- |
|
||||
| `assistant_accounts_master` | `/PersonnelManagement/SearchAssistantInfo` | data.assistantInfos |
|
||||
| `assistant_service_records` | `/AssistantPerformance/GetOrderAssistantDetails` | data.orderAssistantDetails |
|
||||
| `assistant_cancellation_records` | `/AssistantPerformance/GetAbolitionAssistant` | data.abolitionAssistants |
|
||||
| `goods_stock_movements` | `/GoodsStockManage/QueryGoodsOutboundReceipt` | data.queryDeliveryRecordsList |
|
||||
| `goods_stock_summary` | `/TenantGoods/GetGoodsStockReport` | data |
|
||||
| `group_buy_packages` | `/PackageCoupon/QueryPackageCouponList` | data.packageCouponList |
|
||||
| `group_buy_redemption_records` | `/Site/GetSiteTableUseDetails` | data.siteTableUseDetailsList |
|
||||
| `member_profiles` | `/MemberProfile/GetTenantMemberList` | data.tenantMemberInfos |
|
||||
| `member_balance_changes` | `/MemberProfile/GetMemberCardBalanceChange` | data.tenantMemberCardLogs |
|
||||
| `member_stored_value_cards` | `/MemberProfile/GetTenantMemberCardList` | data.tenantMemberCards |
|
||||
| `payment_transactions` | `/PayLog/GetPayLogListPage` | data |
|
||||
| `platform_coupon_redemption_records` | `/Promotion/GetOfflineCouponConsumePageList` | data |
|
||||
| `recharge_settlements` | `/Site/GetRechargeSettleList` | data.settleList |
|
||||
| `refund_transactions` | `/Order/GetRefundPayLogList` | data |
|
||||
| `settlement_records` | `/Site/GetAllOrderSettleList` | data.settleList |
|
||||
| `settlement_ticket_details` | `/Order/GetOrderSettleTicketNew` | (整包原始 JSON) |
|
||||
| `site_tables_master` | `/Table/GetSiteTables` | data.siteTables |
|
||||
| `stock_goods_category_tree` | `/TenantGoodsCategory/QueryPrimarySecondaryCategory` | data.goodsCategoryList |
|
||||
| `store_goods_master` | `/TenantGoods/GetGoodsInventoryList` | data.orderGoodsList |
|
||||
| `store_goods_sales_records` | `/TenantGoods/GetGoodsSalesList` | data.orderGoodsLedgers |
|
||||
| `table_fee_discount_records` | `/Site/GetTaiFeeAdjustList` | data.taiFeeAdjustInfos |
|
||||
| `table_fee_transactions` | `/Site/GetSiteTableOrderDetails` | data.siteTableUseDetailsList |
|
||||
| `tenant_goods_master` | `/TenantGoods/QueryTenantGoods` | data.tenantGoodsList |
|
||||
| ODS 表名 | 接口 Path | 数据列表路径 |
|
||||
| ------------------------------------ | ------------------------------------------------- | ----------------------------- |
|
||||
| assistant_accounts_master | /PersonnelManagement/SearchAssistantInfo | data.assistantInfos |
|
||||
| assistant_service_records | /AssistantPerformance/GetOrderAssistantDetails | data.orderAssistantDetails |
|
||||
| assistant_cancellation_records | /AssistantPerformance/GetAbolitionAssistant | data.abolitionAssistants |
|
||||
| goods_stock_movements | /GoodsStockManage/QueryGoodsOutboundReceipt | data.queryDeliveryRecordsList |
|
||||
| goods_stock_summary | /TenantGoods/GetGoodsStockReport | data |
|
||||
| group_buy_packages | /PackageCoupon/QueryPackageCouponList | data.packageCouponList |
|
||||
| group_buy_redemption_records | /Site/GetSiteTableUseDetails | data.siteTableUseDetailsList |
|
||||
| member_profiles | /MemberProfile/GetTenantMemberList | data.tenantMemberInfos |
|
||||
| member_balance_changes | /MemberProfile/GetMemberCardBalanceChange | data.tenantMemberCardLogs |
|
||||
| member_stored_value_cards | /MemberProfile/GetTenantMemberCardList | data.tenantMemberCards |
|
||||
| payment_transactions | /PayLog/GetPayLogListPage | data |
|
||||
| platform_coupon_redemption_records | /Promotion/GetOfflineCouponConsumePageList | data |
|
||||
| recharge_settlements | /Site/GetRechargeSettleList | data.settleList |
|
||||
| refund_transactions | /Order/GetRefundPayLogList | data |
|
||||
| settlement_records | /Site/GetAllOrderSettleList | data.settleList |
|
||||
| settlement_ticket_details | /Order/GetOrderSettleTicketNew | 完整 JSON |
|
||||
| site_tables_master | /Table/GetSiteTables | data.siteTables |
|
||||
| stock_goods_category_tree | /TenantGoodsCategory/QueryPrimarySecondaryCategory| data.goodsCategoryList |
|
||||
| store_goods_master | /TenantGoods/GetGoodsInventoryList | data.orderGoodsList |
|
||||
| store_goods_sales_records | /TenantGoods/GetGoodsSalesList | data.orderGoodsLedgers |
|
||||
| table_fee_discount_records | /Site/GetTaiFeeAdjustList | data.taiFeeAdjustInfos |
|
||||
| table_fee_transactions | /Site/GetSiteTableOrderDetails | data.siteTableUseDetailsList |
|
||||
| tenant_goods_master | /TenantGoods/QueryTenantGoods | data.tenantGoodsList |
|
||||
|
||||
> 完整清单与字段级映射请结合 `docs/` 下映射文档与各 ODS/DWD DDL 参照执行。
|
||||
> 完整字段级映射见 `docs/` 与 ODS/DWD DDL。
|
||||
|
||||
---
|
||||
|
||||
## 12. DWD 维度与建模原则(核心要点)
|
||||
|
||||
1. **粒度唯一、原子**:一张 DWD 表只承载一种业务事件粒度(结账、台费流水、助教服务、余额变动等),禁止混粒度与混汇总。
|
||||
2. **以业务过程建模**:先梳理真实业务链路,再拆表/拆维度,不以 JSON 列表结构生搬硬套。
|
||||
3. **主键明确、外键统一**:统一命名(如 `site_id`、`member_id`、`table_id`、`order_settle_id`、`order_trade_no`),避免后续主题层拼接歧义。
|
||||
4. **保留明细,不做过度汇总**:DWD 仅存明细,聚合到 DWS 完成。
|
||||
5. **统一清洗且可追溯**:类型/单位/枚举标准化,并保留源主键与原始字段确保可追溯。
|
||||
6. **扁平化、去嵌套**:数组拆子表,重复 profile 抽维度,去除分页壳。
|
||||
7. **长期稳定、可扩展**:优先加字段/增表/在 DWS 派生,避免频繁重构 DWD 表。
|
||||
## 12. DWD 维度与建模要点
|
||||
1. 颗粒一致、单一业务键:一张 DWD 表只承载一种业务事件/颗粒,避免混颗粒。
|
||||
2. 先理解业务链路,再建模;不要机械按 JSON 列表建表。
|
||||
3. 业务键统一:site_id、member_id、table_id、order_settle_id、order_trade_no 等必须一致命名。
|
||||
4. 保留明细,不过度汇总;聚合留到 DWS/报表。
|
||||
5. 清洗标准化同时保留溯源字段(源主键、时间、金额、payload)。
|
||||
6. 去嵌套与解耦:数组展开子行,重复 profile 提炼维度。
|
||||
7. 演进优先加列/加表,减少对已有表结构的破坏。
|
||||
|
||||
---
|
||||
|
||||
## 13. 当前状态(2025-12-09)
|
||||
|
||||
- 示例 JSON 已全量灌入;DWD 行数与 ODS 对齐。
|
||||
- 分类维度已展平大类+子类:`dim_goods_category` 26 行(`category_level/leaf` 已赋值)。
|
||||
- 部分空值来自上游源数据为空;补值需先确认上游是否提供。
|
||||
- 示例 JSON 已全量灌入,DWD 行数与 ODS 对齐。
|
||||
- 分类维度已展平大类+子类:`dim_goods_category` 26 行(category_level/leaf 已赋值)。
|
||||
- 部分空字段源数据即为空,如需补值请先确认上游。
|
||||
|
||||
---
|
||||
|
||||
## 14. 可精简/归档
|
||||
|
||||
- `tmp/`、`tmp/etl_billiards_misc/`、`etl_billiards/tmp & Delete/` 下草稿/旧备份/一次性脚本不参与运行,可按需归档或清理。
|
||||
- 顶层仅保留必要文件(README、requirements、run_etl.*、.env/.env.example);其余临时文件已移至 `tmp/`。
|
||||
- `tmp/`、`tmp/etl_billiards_misc/` 中草稿、旧备份、调试脚本仅供参考,不影响运行。
|
||||
- 根级保留必要文件(README、requirements、run_etl.*、.env/.env.example),其他临时文件已移至 tmp。
|
||||
|
||||
---
|
||||
|
||||
## 15. 常见问题(FAQ)
|
||||
|
||||
- **字段空值**:如映射存在且源列非空仍为空,先检查上游 JSON 是否缺值;维度 SCD2 按全量合并。
|
||||
- **DSN/目录缺失**:确认 `.env` 中 `PG_DSN`、`INGEST_SOURCE_DIR` 与本地一致。
|
||||
- **新增任务**:在 `tasks/` 实现并注册到 `task_registry.py`,必要时补充 DDL 与映射。
|
||||
- **连接/权限**:网络/账号/权限检查;脚本执行权限(如 `chmod +x run_etl.sh`)。
|
||||
|
||||
---
|
||||
|
||||
> 以上为合并后的单点说明文档。若需拆分为「快速开始 / 架构设计 / 迁移指南 / 开发扩展」等多份文档,可按章节直接拆分。
|
||||
## 15. FAQ
|
||||
- 字段空值:若映射已存在且源列非空仍为空,再检查上游 JSON;维度 SCD2 按全量合并。
|
||||
- DSN/路径:确认 `.env` 中 `PG_DSN`、`INGEST_SOURCE_DIR` 与本地一致。
|
||||
- 新增任务:在 `tasks/` 实现并注册到 `task_registry.py`,必要时同步更新 DDL 与映射。
|
||||
- 权限/运行:检查网络、账号权限;脚本需执行权限(如 `chmod +x run_etl.sh`)。
|
||||
|
||||
Reference in New Issue
Block a user