234 lines
9.2 KiB
Markdown
234 lines
9.2 KiB
Markdown
# GMV Analytics
|
|
|
|
按项目、店铺和日期统计销售金额、退款金额及 GMV,并同步到飞书多维表格。支持本地手动执行、历史日期补数,以及通过 Docker + Prefect 定时运行。
|
|
|
|
## 项目介绍
|
|
|
|
数据来自 PostgreSQL,通过 `店铺映射表.xlsx` 将 BI 店铺名称转换为业务店铺名称,再按项目和月份匹配飞书目标表。
|
|
|
|
- 支持项目:大眼睛、羽心堂、MMMJ、EM、春回盏、BROKEN ZOO。
|
|
- 计算口径:`GMV = 销售金额 - 退款金额`,具体取数 SQL 位于 `project_bitable_common.py`。
|
|
- 本地流水线逐日查询销售额和退款额,计算 GMV,写入对应项目的月份表。
|
|
- 当前流水线使用“日期”“指标”和各店铺数值列,指标包括“销售金额”“退款金额”“GMV”“汇总GMV”。汇总逻辑读取表内当月、不晚于处理日期的 GMV 记录进行累加。
|
|
- 可选择同步完成后向飞书群发送通知。
|
|
|
|
## 环境准备
|
|
|
|
需要 Python 3.12 或以上版本、可连接的 PostgreSQL 数据库,以及具有目标多维表格访问和写入权限的飞书应用。
|
|
|
|
以下命令均在项目根目录执行。已有 Conda / Python 环境时,先激活该环境。
|
|
|
|
使用 uv 安装依赖并进入虚拟环境:
|
|
|
|
```bash
|
|
uv sync
|
|
source .venv/bin/activate
|
|
```
|
|
|
|
也可以在已有 Python 环境中安装项目声明的依赖:
|
|
|
|
```bash
|
|
python - <<'PY'
|
|
import subprocess
|
|
import sys
|
|
import tomllib
|
|
from pathlib import Path
|
|
|
|
config = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8"))
|
|
subprocess.check_call([sys.executable, "-m", "pip", "install", *config["project"]["dependencies"]])
|
|
PY
|
|
```
|
|
|
|
## 配置 .env
|
|
|
|
在项目根目录创建或编辑 `.env`。下面均为占位值,请替换为实际配置:
|
|
|
|
```dotenv
|
|
ANALYTICS_DB_HOST=your-db-host
|
|
ANALYTICS_DB_PORT=5432
|
|
ANALYTICS_DB_NAME=your-db-name
|
|
ANALYTICS_DB_USER=your-db-user
|
|
ANALYTICS_DB_PASSWORD=your-db-password
|
|
|
|
FEISHU_APP_ID=your-app-id
|
|
FEISHU_APP_SECRET=your-app-secret
|
|
FEISHU_BASE_URL=https://your-tenant.feishu.cn/base/your-base-token
|
|
|
|
SYNC_START_DATE=2026-09-01
|
|
```
|
|
|
|
脚本自动加载项目根目录的 `.env`,已存在的进程环境变量优先于 `.env`。当前加载器按 `KEY=value` 读取,值不要额外加引号,也不要在值后追加行内注释。
|
|
|
|
`.env` 已加入 `.gitignore`,用于保存本地配置。
|
|
|
|
可选配置:
|
|
|
|
| 变量 | 用途与默认行为 |
|
|
| --- | --- |
|
|
| `PROJECT_MAPPING_FILE` | 店铺映射文件路径;不设置时使用脚本目录下的 `店铺映射表.xlsx` |
|
|
| `SYNC_START_DATE` | 本地流水线默认开始日期;未设置时为 `2026-04-01` |
|
|
| `FEISHU_CHAT_ID` | 应用机器人通知的目标群;配置后优先使用此方式 |
|
|
| `FEISHU_BOT_WEBHOOK` | 未设置群 ID 时使用的群机器人 Webhook |
|
|
| `FEISHU_REPORT_IMAGE_PATH` | 应用机器人通知使用的本地预览图路径 |
|
|
| `FEISHU_STORE_FIELD_NAME` | 独立脚本使用的店铺字段名,默认 `店铺名称` |
|
|
| `PREFECT_API_URL` | Prefect Server API 地址,本地流水线不需要 |
|
|
| `LOG_DIR` | 日志目录,默认项目下的 `logs` |
|
|
| `LOG_LEVEL` | 日志级别,默认 `INFO` |
|
|
|
|
映射文件读取第一个活动工作表,跳过第一行表头。三列及以上时,使用第 2 列作为业务店铺名称、第 3 列作为 BI 店铺名称;只有两列时,依次为业务店铺名称、BI 店铺名称。
|
|
|
|
## 本地执行
|
|
|
|
本地入口为 `run_project_bitable_pipeline.py`,可直接使用 Python 运行,无需启动 Docker 或 Prefect Server。未激活 uv 虚拟环境时,也可以将以下命令中的 `python` 替换为 `uv run python`。
|
|
|
|
### 指定一天
|
|
|
|
将开始日期和结束日期设为同一天:
|
|
|
|
```bash
|
|
python run_project_bitable_pipeline.py \
|
|
--start-date 2026-09-07 \
|
|
--end-date 2026-09-07 \
|
|
--no-notify \
|
|
--skip-missing-tables
|
|
```
|
|
|
|
### 指定日期范围
|
|
|
|
例如同步 2026 年 9 月 1 日至 9 月 7 日,包含首尾两天:
|
|
|
|
```bash
|
|
python run_project_bitable_pipeline.py \
|
|
--start-date 2026-09-01 \
|
|
--end-date 2026-09-07 \
|
|
--no-notify \
|
|
--skip-missing-tables
|
|
```
|
|
|
|
`--no-notify` 表示只同步数据,不发群通知。需要通知时,配置通知渠道并去掉该参数。
|
|
|
|
`--skip-missing-tables` 表示找不到对应表时记录日志并继续处理其他项目和日期,不会自动创建月份表。当前实现也会跳过匹配到多个表、映射指定表不存在等表匹配错误;应查看跳过日志确认哪些项目尚未同步。数据库连接或飞书写入失败等其他错误仍会中断运行。
|
|
|
|
### 预览执行
|
|
|
|
```bash
|
|
python run_project_bitable_pipeline.py \
|
|
--start-date 2026-09-01 \
|
|
--end-date 2026-09-07 \
|
|
--dry-run \
|
|
--no-notify \
|
|
--skip-missing-tables
|
|
```
|
|
|
|
`--dry-run` 会查询数据库、获取飞书访问令牌和表列表,并输出计划处理的表、日期和指标,不写入飞书、不发通知。因此仍需有效的数据库和飞书配置。
|
|
|
|
### 常用参数
|
|
|
|
| 参数 | 说明 |
|
|
| --- | --- |
|
|
| `--start-date YYYY-MM-DD` | 开始日期,默认读取 `SYNC_START_DATE` |
|
|
| `--end-date YYYY-MM-DD` | 结束日期,默认运行机器本地日期的昨天 |
|
|
| `--no-notify` | 跳过飞书群通知,默认未开启 |
|
|
| `--skip-missing-tables` | 跳过表匹配错误,默认未开启 |
|
|
| `--dry-run` | 预览,不执行飞书写入和通知 |
|
|
| `--mapping-file PATH` | 指定店铺映射 Excel 文件,覆盖环境变量配置 |
|
|
| `--table-map-file PATH` | 指定项目月份到飞书表名的 JSON 映射 |
|
|
| `--base-url URL` | 指定飞书多维表格地址;仍需在环境中配置 `FEISHU_BASE_URL`,当前参数解析会读取其默认值 |
|
|
|
|
日期范围的结束日期不能早于开始日期。本地流水线未传日期时会从默认开始日期一直同步到昨天;补数时建议明确传入两个日期。
|
|
|
|
完整参数可在配置好 `.env` 后查看:
|
|
|
|
```bash
|
|
python run_project_bitable_pipeline.py --help
|
|
```
|
|
|
|
## 常见问题
|
|
|
|
### 映射表路径不存在
|
|
|
|
如果出现 `FileNotFoundError`,且路径仍指向其他机器上的 `/Users/idss/...`,请修改 `.env` 中的 `PROJECT_MAPPING_FILE`,或删除该配置以使用项目自带文件。
|
|
|
|
也可以在命令中添加以下参数,直接覆盖旧路径:
|
|
|
|
```bash
|
|
--mapping-file ./店铺映射表.xlsx
|
|
```
|
|
|
|
### 找不到对应月份的飞书表
|
|
|
|
例如“羽心堂”只有 3—8 月表,执行 9 月数据时会报 `未找到匹配表`。临时跳过可添加 `--skip-missing-tables`;补齐月份表后,再运行对应日期范围。
|
|
|
|
### 表名不规范或匹配到多个表
|
|
|
|
创建 `table_map.json`,键格式为 `项目:YYYY-MM`,值为飞书中实际存在的完整表名:
|
|
|
|
```json
|
|
{
|
|
"大眼睛:2026-09": "大眼睛买买买-9月",
|
|
"羽心堂:2026-09": "羽心堂-9月"
|
|
}
|
|
```
|
|
|
|
执行时添加 `--table-map-file ./table_map.json`。自动匹配支持项目别名和月份文本,跨年份存在同名月份表时应显式指定映射。
|
|
|
|
## Prefect 执行与定时调度
|
|
|
|
手动触发一次 Prefect 数据同步:
|
|
|
|
```bash
|
|
python prefect_gmv_scheduler.py \
|
|
--mode sync \
|
|
--start-date 2026-09-01 \
|
|
--end-date 2026-09-07 \
|
|
--skip-missing-tables
|
|
```
|
|
|
|
| 模式 | 行为 |
|
|
| --- | --- |
|
|
| `--mode sync` | 只同步数据 |
|
|
| `--mode notify` | 只发送通知 |
|
|
| `--mode all` | 先同步再通知,默认模式 |
|
|
|
|
Prefect 同步未显式指定日期时,默认处理截至昨天的最近 5 天,并以 `SYNC_START_DATE` 为最早边界。通知未指定日期时,优先读取上次成功同步保存的日期范围。
|
|
|
|
`prefect.yaml` 定义了北京时间每天 08:00 同步、09:00 通知两条调度。部署前需准备可访问的 Prefect Server,并配置 `PREFECT_API_URL`。
|
|
|
|
```bash
|
|
docker compose up -d --build
|
|
docker exec -it prefect-gmv-worker sh -lc 'cd /app && prefect deploy --all'
|
|
```
|
|
|
|
Compose 启动的是等待调度任务的 worker。定时任务需要跳过缺失表时,将 `prefect.yaml` 对应 deployment 的 `parameters.skip_missing_tables` 改为 `true`,再重新执行 `prefect deploy --all` 注册配置。
|
|
|
|
更多部署说明见项目中的 `DOCKER_PREFECT_USAGE.md`;其中示例的本机目录需要替换为实际项目目录。
|
|
|
|
## 文件说明与日志
|
|
|
|
| 文件 | 用途 |
|
|
| --- | --- |
|
|
| `run_project_bitable_pipeline.py` | 本地完整流水线入口,使用日期 / 指标行结构 |
|
|
| `project_bitable_common.py` | SQL、店铺映射、表匹配、飞书 API、同步与通知逻辑 |
|
|
| `prefect_gmv_scheduler.py` | Prefect flow、日期窗口和执行模式 |
|
|
| `generate_project_sales_csv.py` | 独立销售额同步脚本 |
|
|
| `generate_project_refund_csv.py` | 独立退款额同步脚本 |
|
|
| `generate_project_gmv_csv.py` | 从飞书销售额和退款额字段计算并回写 GMV |
|
|
| `店铺映射表.xlsx` | BI 店铺与业务店铺名称映射 |
|
|
| `logging_config.py` | 控制台与轮转文件日志 |
|
|
| `prefect.yaml` | 定时任务与 work pool 配置 |
|
|
| `docker-compose.yaml` / `Dockerfile` | 容器运行与构建配置 |
|
|
|
|
三个 `generate_project_*_csv.py` 文件虽带有 `csv` 后缀,实际执行飞书同步;它们使用以店铺为记录、日期指标为字段的结构,与当前完整流水线的表结构不同。日常运行使用完整流水线入口。
|
|
|
|
默认日志写入 `logs/gmv_sync.log`,单个文件达到 10 MiB 后轮转,保留 7 个备份。
|
|
|
|
```bash
|
|
tail -f logs/gmv_sync.log
|
|
```
|
|
|
|
Docker worker 日志:
|
|
|
|
```bash
|
|
docker logs -f prefect-gmv-worker
|
|
```
|