Files
inventory_analytics/PROJECT_GUIDE.md
T

5.1 KiB
Raw Blame History

Inventory Analytics 工程说明

项目概览

当前工程包含两条独立业务链路:

  • 委外批次库存上传:通过本地网页上传 Excel/CSV 文件,保存原始文件,并逐行写入 Raw PostgreSQL 表。
  • 飞书库存同步:从 Analytics PostgreSQL 查询库存、挂单量、销售和商品信息,并同步到飞书多维表格。

目录结构

inventory_analytics/
├── .env
├── PROJECT_GUIDE.md
├── REFACTOR_PLAN.md
├── upload_inventory_page.py
├── list_feishu_base_tables.py
└── inventory_sync/
    ├── __init__.py
    ├── cli.py
    ├── feishu.py
    ├── postgres.py
    ├── service.py
    ├── settings.py
    ├── specs.py
    └── sql.py

运行后会自动创建或使用:

batch_inventory_data/

该目录保存上传的委外批次库存原始文件,不纳入业务代码结构。

环境变量

委外批次库存上传

上传页使用 .env 中的 Raw 数据库配置:

RAW_DB_HOST
RAW_DB_PORT
RAW_DB_USER
RAW_DB_PASSWORD
RAW_DB_NAME

写入目标:

raw_data.wangdian_batch_inventory

表结构由 upload_inventory_page.py 内的 get_create_table_sql() 创建:

payload JSONB NOT NULL,
start_time TIMESTAMP WITH TIME ZONE,
end_time TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
reserved_1 TEXT,
reserved_2 TEXT

飞书库存同步

飞书同步使用 .env 中的飞书和 Analytics 数据库配置:

FEISHU_APP_ID
FEISHU_APP_SECRET
FEISHU_BASE_URL
FEISHU_APP_TOKEN
ANALYTICS_DB_HOST
ANALYTICS_DB_PORT
ANALYTICS_DB_USER
ANALYTICS_DB_PASSWORD
ANALYTICS_DB_NAME

FEISHU_APP_TOKEN 可选;当 FEISHU_BASE_URL 已包含 /base/ 或 /wiki/ 时,可以不单独配置。

委外批次库存上传

启动上传页:

python3 upload_inventory_page.py

打开页面:

http://127.0.0.1:8080

支持文件:

  • .xlsx
  • .xlsm
  • .xls
  • .csv

单文件大小限制:

200 MB

上传成功后会执行:

  1. 保存文件到 batch_inventory_data/。
  2. 解析 Excel/CSV 为行数据。
  3. 创建 Raw schema/table 和 created_at 索引。
  4. 每一行插入一条 JSONB payload。

payload 示例:

{
  "source_file": "委外批次库存.xlsx",
  "stored_file": "20260423_172410_委外批次库存.xlsx",
  "uploaded_at": "2026-04-23T18:20:00",
  "total_count": 120,
  "inventory_data": {
    "货品编码": "SKU001",
    "批次": "BATCH001",
    "数量": 10
  }
}

飞书库存同步

查看飞书 Base 表:

python3 list_feishu_base_tables.py --action feishu

只查询 PostgreSQL:

python3 list_feishu_base_tables.py --action postgres

同步品牌库存到飞书:

python3 list_feishu_base_tables.py --action sync-brand

执行完整流程:

python3 list_feishu_base_tables.py --action all

同步目标配置在 inventory_sync/specs.py:

BRAND_SYNC_TARGETS = [
    BrandSyncTarget(brand_name="羽心堂", table_name="羽心堂", warehouse_keys=(2, 3, 7, 13)),
]

字段映射也集中维护在 inventory_sync/specs.py 的 FIELD_SPECS。

日志说明

项目使用结构化事件日志,格式:

YYYY-MM-DD HH:MM:SS LEVEL logger_name 事件=中文事件描述 中文字段=字段值 ...

上传页日志输出到 stdout,典型事件包括:

事件=上传服务启动中
事件=收到上传请求
事件=已解析上传文件
事件=上传文件已保存
事件=开始解析库存文件
事件=已解析Excel工作表
事件=已加载Raw数据库配置
事件=Raw数据表确认完成
事件=Raw数据写入完成
事件=上传请求处理完成

飞书同步日志输出到 stderr,JSON 结果仍输出到 stdout,便于命令行管道消费。典型事件包括:

事件=飞书同步入口启动
事件=飞书同步动作开始
事件=已加载环境变量文件
事件=开始读取飞书Base信息
事件=开始查询PostgreSQL
事件=开始同步品牌数据
事件=开始同步目标飞书表
事件=目标飞书表同步完成
事件=飞书同步入口完成

查看和关闭上传服务

查看 8080 端口:

lsof -nP -iTCP:8080 -sTCP:LISTEN

关闭服务:

kill <PID>

如果普通关闭失败:

kill -9 <PID>

验证命令

语法检查:

python3 -m py_compile upload_inventory_page.py list_feishu_base_tables.py inventory_sync/*.py

查看飞书同步帮助:

python3 list_feishu_base_tables.py --help

本地启动上传页:

python3 upload_inventory_page.py

维护原则

  • 上传 Raw 数据保持原始粒度,每行一条 payload,不在上传阶段做复杂业务清洗。
  • 飞书同步使用 inventory_sync/specs.py 管理品牌目标和字段映射。
  • SQL 调整优先修改 inventory_sync/sql.py。
  • 入口脚本保持稳定,便于人工执行和后续定时任务接入。
  • 日志新增时优先使用 事件=<中文描述>,并输出足够定位问题的关键字段。