Files
gmv-analytics/README.md
T
2026-09-08 11:22:42 +08:00

9.2 KiB

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 安装依赖并进入虚拟环境:

uv sync
source .venv/bin/activate

也可以在已有 Python 环境中安装项目声明的依赖:

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。下面均为占位值,请替换为实际配置:

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。

指定一天

将开始日期和结束日期设为同一天:

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 日,包含首尾两天:

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 表示找不到对应表时记录日志并继续处理其他项目和日期,不会自动创建月份表。当前实现也会跳过匹配到多个表、映射指定表不存在等表匹配错误;应查看跳过日志确认哪些项目尚未同步。数据库连接或飞书写入失败等其他错误仍会中断运行。

预览执行

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 后查看:

python run_project_bitable_pipeline.py --help

常见问题

映射表路径不存在

如果出现 FileNotFoundError,且路径仍指向其他机器上的 /Users/idss/...,请修改 .env 中的 PROJECT_MAPPING_FILE,或删除该配置以使用项目自带文件。

也可以在命令中添加以下参数,直接覆盖旧路径:

--mapping-file ./店铺映射表.xlsx

找不到对应月份的飞书表

例如“羽心堂”只有 3—8 月表,执行 9 月数据时会报 未找到匹配表。临时跳过可添加 --skip-missing-tables;补齐月份表后,再运行对应日期范围。

表名不规范或匹配到多个表

创建 table_map.json,键格式为 项目:YYYY-MM,值为飞书中实际存在的完整表名:

{
  "大眼睛:2026-09": "大眼睛买买买-9月",
  "羽心堂:2026-09": "羽心堂-9月"
}

执行时添加 --table-map-file ./table_map.json。自动匹配支持项目别名和月份文本,跨年份存在同名月份表时应显式指定映射。

Prefect 执行与定时调度

手动触发一次 Prefect 数据同步:

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。

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 个备份。

tail -f logs/gmv_sync.log

Docker worker 日志:

docker logs -f prefect-gmv-worker