Files
BXY0414 e234bfbe7a 修feat: 渠道库存同步支持字段任意排序并增加字段异常告警
- 按字段名校验并写入渠道库存,取消字段顺序校验及表头重建
- 严格校验必填字段名称、类型和数字格式,失败时不修改表头或记录
- 字段校验失败时发送飞书群通知
- 添加字段校验与通知流程测试
- 忽略 Python 字节码、__pycache__ 和 .DS_Store
2026-07-22 14:28:23 +08:00

307 lines
8.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Inventory Analytics
Inventory Analytics 是一个内部库存数据处理项目,围绕委外批次库存上传、渠道库存统计同步、批次库存统计报表三条业务链路运行。项目从 Raw PostgreSQL、Analytics PostgreSQL 和飞书多维表格之间同步与汇总库存数据,并支持本地执行、Docker 部署和 Prefect 定时调度。
## 项目目标
- 上传委外批次库存文件,并写入 Raw 数据库。
- 从 Analytics 数据库读取渠道库存、锁定库存、销售和商品信息。
- 生成批次库存统计数据,可输出本地报表,也可同步到飞书多维表格。
- 通过 Prefect 每天定时执行渠道库存统计和批次库存统计同步。
- 统一日志输出,保留关键节点与异常信息,同时避免输出数据库、飞书等敏感配置。
## 核心链路
### 1. 委外批次库存上传
入口:
```bash
python3 scripts/upload_batch_inventory.py
```
功能:
- 启动本地上传页面。
- 支持 Excel 和 CSV 文件上传。
- 保存原始文件到 `batch_inventory_data/`。
- 将解析后的每一行写入 Raw PostgreSQL 的 `raw_data.wangdian_batch_inventory`。
兼容入口:
```bash
python3 upload_inventory_page.py
```
### 2. 渠道库存统计同步飞书
入口:
```bash
python3 scripts/sync_channel_inventory.py
```
功能:
- 读取飞书 Base 与目标表信息。
- 查询 Analytics PostgreSQL 中的渠道库存数据。
- 按目标品牌和飞书字段配置整理数据。
- 清空并重写飞书目标表记录。
可选动作:
```bash
python3 scripts/sync_channel_inventory.py --action feishu
python3 scripts/sync_channel_inventory.py --action postgres
python3 scripts/sync_channel_inventory.py --action sync-brand
python3 scripts/sync_channel_inventory.py --action all
```
兼容入口:
```bash
python3 sync_channel_inventory.py --action all
python3 list_feishu_base_tables.py --action all
```
### 3. 批次库存统计报表
入口:
```bash
python3 scripts/generate_batch_inventory_report.py
```
功能:
- 读取 Raw 数据库中最新的委外批次库存。
- 查询 Analytics 数据库中的店铺库存、锁定库存、商品信息和近 30 天销售数量。
- 按批次维度汇总库存数据。
- 计算保质期、距离到期天数、效期比例等字段。
- 可输出本地 Excel/CSV 报表。
- 可同步到飞书 `批次库存` 表。
常用参数:
```bash
python3 scripts/generate_batch_inventory_report.py --skip-feishu-sync
python3 scripts/generate_batch_inventory_report.py --skip-report-output
python3 scripts/generate_batch_inventory_report.py --output reports/custom.xlsx
python3 scripts/generate_batch_inventory_report.py --feishu-table 批次库存
```
兼容入口:
```bash
python3 generate_batch_inventory_report.py
python3 generate_yxt_batch_inventory_report.py
```
## 目录结构
```text
.
├── inventory_analytics/ # 当前主包
│ ├── config.py # 配置加载
│ ├── logging_utils.py # 日志与脱敏
│ ├── paths.py # 项目路径
│ ├── batch_upload/ # 委外批次库存上传
│ ├── batch_inventory_report/ # 批次库存统计报表
│ ├── channel_inventory_sync/ # 渠道库存同步入口封装
│ ├── db/ # 数据库相关扩展位置
│ └── feishu/ # 飞书客户端封装
├── inventory_sync/ # 渠道库存同步历史实现,当前仍在复用
├── scripts/ # 推荐命令入口
├── batch_inventory_data/ # 上传原始文件归档目录
├── logs/ # 日志目录
├── reports/ # 本地报表输出目录
├── Dockerfile
├── docker-compose.yaml
├── prefect.yaml
├── prefect_inventory_scheduler.py # Prefect flow 定义与本地触发入口
└── PROJECT_GUIDE.md # 更详细的维护说明
```
## 配置
项目通过 `.env` 或当前 Shell 环境变量读取配置。主要配置项如下:
Raw 数据库:
```text
RAW_DB_HOST
RAW_DB_PORT
RAW_DB_USER
RAW_DB_PASSWORD
RAW_DB_NAME
```
Analytics 数据库:
```text
ANALYTICS_DB_HOST
ANALYTICS_DB_PORT
ANALYTICS_DB_USER
ANALYTICS_DB_PASSWORD
ANALYTICS_DB_NAME
```
飞书:
```text
FEISHU_APP_ID
FEISHU_APP_SECRET
FEISHU_BASE_URL
FEISHU_APP_TOKEN
```
Prefect:
```text
PREFECT_API_URL
```
说明:
- `.env` 不应提交到版本库。
- 日志默认不会输出数据库连接信息、飞书 app token、飞书 base URL、表 ID、密码或密钥。
- `FEISHU_APP_TOKEN` 可选;当 `FEISHU_BASE_URL` 已包含 `/base/` 或 `/wiki/` 时,可以不单独配置。
- 渠道库存同步允许飞书字段任意排序,但会严格校验必填字段名称、类型和数字格式。校验失败时不会修改表头或记录,并会向指定的飞书通知群发送错误消息。应用需开启机器人能力、具备发送群消息权限,并已加入该通知群。
## Prefect 调度
项目定义了两个 Prefect deployment,每个 deployment 用一条 cron 覆盖 09:15 和 19:15:
- `channel-inventory-sync-0915-1915`:每天 09:15 和 19:15 执行渠道库存统计并写入飞书。
- `batch-inventory-report-0915-1915`:每天 09:15 和 19:15 执行批次库存统计并写入飞书。
注册 deployment:
```bash
sh scripts/register_prefect_deployments.sh
```
该脚本会进入 Docker 容器内,按 deployment 名称分别注册:
```bash
docker compose exec -T prefect-inventory-worker prefect --no-prompt deploy --name channel-inventory-sync-0915-1915
docker compose exec -T prefect-inventory-worker prefect --no-prompt deploy --name batch-inventory-report-0915-1915
```
启动 Docker worker:
```bash
docker compose up -d --build
```
如果调整了 Python 依赖或 Prefect 版本,需要重新构建镜像后再注册 deployment:
```bash
docker compose build --no-cache prefect-inventory-worker
docker compose up -d prefect-inventory-worker
sh scripts/register_prefect_deployments.sh
```
手动触发:
```bash
python3 prefect_inventory_scheduler.py --run-channel-inventory-sync
python3 prefect_inventory_scheduler.py --run-batch-inventory-report
```
本地 serve:
```bash
python3 prefect_inventory_scheduler.py --serve-channel-inventory-sync
python3 prefect_inventory_scheduler.py --serve-batch-inventory-report
```
Prefect 调度下,批次库存统计默认不生成本地 `reports/` 文件,只同步飞书。如需同时生成本地报表,可使用:
```bash
python3 prefect_inventory_scheduler.py --run-batch-inventory-report --write-report-output
```
## 日志策略
日志采用结构化事件格式:
```text
YYYY-MM-DD HH:MM:SS LEVEL logger_name 事件=事件名称 字段=字段值
```
正常执行会输出关键节点:
- 任务启动与完成
- 配置加载完成
- 数据库查询开始与完成
- 数据整理与汇总完成
- 飞书访问令牌获取
- 飞书表读取
- 飞书记录删除与新增数量
- 本地报表是否输出
- 总耗时
异常情况会输出:
- 失败阶段
- 异常类型
- 脱敏后的错误信息
- 已执行耗时
日志不会输出:
- 数据库 host、port、user、password、database name
- 飞书 app id、app secret、app token、base URL
- 飞书 table id、field id、record id
- `.env` 完整路径
- 含 token 的 URL
主要日志文件:
```text
logs/upload_inventory_page.log
logs/sync_channel_inventory.log
logs/generate_batch_inventory_report.log
```
## 开发与验证
安装依赖:
```bash
pip install -e .
```
语法检查:
```bash
PYTHONPYCACHEPREFIX=/tmp/inventory_analytics_pycache python3 -m compileall inventory_analytics inventory_sync scripts prefect_inventory_scheduler.py
```
验证上传页:
```bash
python3 scripts/upload_batch_inventory.py
```
验证渠道库存飞书连接:
```bash
python3 scripts/sync_channel_inventory.py --action feishu
```
验证批次库存本地报表:
```bash
python3 scripts/generate_batch_inventory_report.py --skip-feishu-sync
```
## 维护约定
- 新增业务代码优先放入 `inventory_analytics/`。
- 新命令优先放入 `scripts/`,根目录脚本只作为兼容入口。
- 公共配置、路径和日志逻辑统一使用 `config.py`、`paths.py`、`logging_utils.py`。
- 当前渠道库存同步仍复用 `inventory_sync/`,后续可逐步迁移到 `inventory_analytics/channel_inventory_sync/`。
- 涉及日志输出时,默认只记录业务状态和计数,不记录连接配置、密钥、Token 或内部资源 ID。