Files
Neo-ZQYY/scripts/ops/analyze_dataflow.py

153 lines
4.7 KiB
Python
Raw 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.
"""
数据流结构分析 — CLI 入口
用法:
python scripts/ops/analyze_dataflow.py
python scripts/ops/analyze_dataflow.py --date-from 2025-01-01 --date-to 2025-01-15
python scripts/ops/analyze_dataflow.py --limit 100 --tables settlement_records,payment_transactions
"""
from __future__ import annotations
import argparse
import os
from datetime import datetime
from pathlib import Path
def build_parser() -> argparse.ArgumentParser:
"""
构造 CLI 参数解析器。
参数:
--date-from 数据获取起始日期 (YYYY-MM-DD)
--date-to 数据获取截止日期 (YYYY-MM-DD)
--limit 每端点最大记录数 (默认 200)
--tables 要分析的表名列表 (逗号分隔,缺省=全部)
"""
parser = argparse.ArgumentParser(
description="数据流结构分析 — 采集 API JSON 和 DB 表结构",
)
parser.add_argument(
"--date-from",
type=str,
default=None,
help="数据获取起始日期 (YYYY-MM-DD)",
)
parser.add_argument(
"--date-to",
type=str,
default=None,
help="数据获取截止日期 (YYYY-MM-DD)",
)
parser.add_argument(
"--limit",
type=int,
default=200,
help="每端点最大记录数 (默认 200)",
)
parser.add_argument(
"--tables",
type=str,
default=None,
help="要分析的表名列表 (逗号分隔,缺省=全部)",
)
return parser
def resolve_output_dir() -> Path:
"""
确定输出目录:
1. 优先读取环境变量 SYSTEM_ANALYZE_ROOT
2. 回退到 docs/reports/
3. 确保目录存在(自动创建)
"""
env_root = os.environ.get("SYSTEM_ANALYZE_ROOT")
if env_root:
out = Path(env_root)
else:
out = Path("docs/reports")
out.mkdir(parents=True, exist_ok=True)
return out
def generate_output_filename(dt: "datetime") -> str:
"""生成输出文件名dataflow_YYYY-MM-DD_HHMMSS.md"""
return f"dataflow_{dt.strftime('%Y-%m-%d_%H%M%S')}.md"
def main() -> None:
"""
串联采集流程:
1. 解析 CLI 参数
2. 加载环境变量(.env 分层叠加)
3. 构造 AnalyzerConfig
4. 调用 collect_all_tables() 执行采集
5. 调用 dump_collection_results() 落盘
6. 输出采集摘要到 stdout
"""
from datetime import date as _date, datetime as _datetime
from dotenv import load_dotenv
# ── 1. 解析 CLI 参数 ──
parser = build_parser()
args = parser.parse_args()
# ── 2. 加载环境变量(分层叠加:根 .env < ETL .env < 环境变量) ──
# override=False 保证后加载的不覆盖先加载的环境变量
# 先加载根 .env最低优先级
load_dotenv(Path(".env"), override=False)
# 再加载 ETL 专属 .env中优先级
load_dotenv(Path("apps/etl/connectors/feiqiu/.env"), override=False)
# 真实环境变量(最高优先级)已自动存在于 os.environ
# ── 3. 构造 AnalyzerConfig ──
date_from = _date.fromisoformat(args.date_from) if args.date_from else None
date_to = _date.fromisoformat(args.date_to) if args.date_to else None
tables = [t.strip() for t in args.tables.split(",")] if args.tables else None
output_dir = resolve_output_dir()
from dataflow_analyzer import AnalyzerConfig, ODS_SPECS, collect_all_tables, dump_collection_results
config = AnalyzerConfig(
date_from=date_from,
date_to=date_to,
limit=args.limit,
tables=tables,
output_dir=output_dir,
pg_dsn=os.environ.get("DATABASE_URL") or os.environ.get("PG_DSN", ""),
api_base=os.environ.get("API_BASE", ""),
api_token=os.environ.get("API_TOKEN", ""),
store_id=os.environ.get("STORE_ID", ""),
)
# ── 4. 执行采集(使用本模块的 ODS_SPECS ──
results = collect_all_tables(config, specs=ODS_SPECS)
# ── 5. 落盘 ──
paths = dump_collection_results(results, output_dir)
# ── 6. 输出采集摘要 ──
now = _datetime.now()
filename = generate_output_filename(now)
ok = sum(1 for r in results if r.error is None)
fail = len(results) - ok
total_records = sum(r.record_count for r in results)
print(f"\n{'='*60}")
print(f"数据流结构分析完成")
print(f"{'='*60}")
print(f" 输出目录: {output_dir}")
print(f" 报告文件名: {filename}")
print(f" 分析表数: {len(results)} ({ok} 成功, {fail} 失败)")
print(f" 总记录数: {total_records}")
print(f" 落盘路径:")
for category, p in paths.items():
print(f" {category}: {p}")
print(f"{'='*60}")
if __name__ == "__main__":
main()