9.3 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 |
本地流水线跳过缺失月份表,默认未开启;Prefect 默认开启,并在完成后推送缺失表提醒 |
--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 deployment 默认跳过缺失月份表,并在同步结束后推送一条汇总提醒。修改 prefect.yaml 后,执行 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