学完能做到 每天自动同步一份生产、质量、工资数据到自己的数仓或 BI。
开始之前
- 已能调通列表接口
- 明确要哪些指标、什么粒度
操作步骤
先确认有没有现成的导出
报表页、库存、对账单等位置有「导出」按钮,导出的是 Excel。如果需求只是「每月拉一份」,用导出比写接口省事得多,不必为了自动化而自动化。
接口拉取:按天增量
列表接口大多支持时间范围过滤。增量同步的原则:每次从上一次成功的时间点拉到现在,重叠半天到一天做补偿,靠业务 ID 去重。不要每天全量拉三年数据。
分页要拉到底
limit 最大 200,需要循环拉直到某页返回条数小于 limit。记得在循环里加间隔(100–300ms),连续高速请求会触发限流回 429。
私有化可以直接连库(仅限私有化)
私有化部署数据在你自己的 MySQL 里,可以建只读账号给 BI 直连。这是性能最好的方案,但要注意:① 只能 SELECT;② 避开业务高峰;③ 数据库结构随版本升级会变,直连 SQL 需要跟着维护。SaaS 版不提供数据库直连。
指标口径必须先跟财务对一遍
「产量」是按报工数还是审核通过数?「产值」含不含税?跨月订单算哪个月?这些口径不统一,BI 做出来的数和系统报表对不上,最后没人信 BI。建议先做一个指标口径对照表,双方签字。
给 BI 建独立只读账号
不要用管理员账号拉数据。建一个只给 report.view 之类读取权限点的角色,避免一旦泄露造成写风险。
代码示例
python拉全量(按页循环 + 限速)
import time, requests
def fetch_all(token, path, params=None, page_size=200):
out, offset = [], 0
while True:
p = dict(params or {}, offset=offset, limit=page_size)
r = requests.get(f"https://YOUR_HOST{path}", params=p,
headers={"Authorization": f"Bearer {token}"}, timeout=60)
if r.status_code == 429:
time.sleep(5)
continue
body = r.json()
if body.get("code") != 200:
raise RuntimeError(f"{body.get('code')}: {body.get('msg')}")
items = body["data"].get("items") or []
out.extend(items)
if len(items) < page_size:
break
offset += page_size
time.sleep(0.2) # 主动限速,别把对方打崩
return outsql私有化直连:只读账号 + 避免高峰
-- 建只读账号(在 MySQL 里执行,需 DBA 权限)
CREATE USER 'bi_reader'@'10.%' IDENTIFIED BY '********';
GRANT SELECT ON lightmes.* TO 'bi_reader'@'10.%';
FLUSH PRIVILEGES;
-- 示例:按天汇总审核通过的报工产量
SELECT DATE(r.created_at) AS d,
p.name AS product,
SUM(r.qty_ok) AS qty_ok,
SUM(r.qty_ng) AS qty_ng
FROM report_records r
JOIN skus s ON s.id = r.sku_id
JOIN products p ON p.id = s.product_id
WHERE r.status = 'approved'
AND r.created_at >= CURDATE() - INTERVAL 30 DAY
GROUP BY d, p.name
ORDER BY d DESC;示例中的域名、租户编码、密钥请替换成你自己的。生产环境不要把密钥写进前端代码。
容易踩的坑
拉到的数据比系统报表少?
大概率是分页没拉完,或者时间过滤条件漏了边界(比如按 created_at 过滤但业务上应该按 finished_at)。先用小范围数据跟页面数字逐条核对。
直连库后升级版本,SQL 报错了?
结构变更会发生(加字段、改类型)。缓解办法:① 只查稳定的宽表/历史表;② SQL 集中管理,升级后跑一次回归;③ 关键报表改成调接口,避免直连。
接口拉取太慢撑不住?
先看是不是逐条查详情(N+1)。列表接口已经返回大部分字段,详情只在必要时再查。另外考虑拉宽时间粒度:BI 日更就够,不必实时。