"""快速诊断 SPI 溢出 - 直接查 dwd_settlement_head""" import os, math from pathlib import Path from dotenv import load_dotenv import psycopg2 load_dotenv(Path(__file__).resolve().parents[2] / ".env") dsn = os.environ["PG_DSN"] conn = psycopg2.connect(dsn, connect_timeout=10) cur = conn.cursor() sid = 2790685415443269 # 1. 查消费极值 cur.execute(""" SELECT MAX(pay_amount), MIN(pay_amount), COUNT(*) FROM dwd.dwd_settlement_head WHERE site_id = %s AND settle_type IN (1,3) AND pay_time >= NOW() - INTERVAL '90 days' """, (sid,)) r = cur.fetchone() print(f"settle_head 90d: max={r[0]}, min={r[1]}, count={r[2]}") # 2. 模拟最大 score max_pay = float(r[0] or 0) level = (0.30 * math.log1p(max_pay/500) + 0.30 * math.log1p(max_pay/1500) + 0.20 * math.log1p(max_pay/200) + 0.20 * math.log1p(0/1000)) speed_abs = math.log1p(max_pay / (1 * 100)) speed = 0.40 * speed_abs raw = 0.60 * level + 0.30 * speed print(f"Simulated max: level={level:.4f}, speed_abs={speed_abs:.4f}, speed={speed:.4f}, raw={raw:.4f}") # 3. 查 SPIMemberFeatures 的 dataclass 定义中 daily_spend_ewma_90 的范围 # 先看 member 级聚合后的极值 cur.execute(""" WITH cs AS ( SELECT COALESCE(NULLIF(s.member_id, 0), 0) AS mid, SUM(COALESCE(s.pay_amount, 0)) AS spend_90, SUM(CASE WHEN pay_time >= NOW() - INTERVAL '30 days' THEN COALESCE(pay_amount,0) ELSE 0 END) AS spend_30, COUNT(*) AS orders_90 FROM dwd.dwd_settlement_head s WHERE s.site_id = %s AND s.settle_type IN (1,3) AND s.pay_time >= NOW() - INTERVAL '90 days' GROUP BY mid ) SELECT mid, spend_30, spend_90, orders_90, spend_90 / GREATEST(orders_90, 1) AS avg_ticket FROM cs ORDER BY spend_90 DESC LIMIT 5 """, (sid,)) print("\nTop 5 spenders:") for r in cur.fetchall(): mid, s30, s90, o90, tk = r s30f, s90f, tkf = float(s30), float(s90), float(tk) lv = (0.30*math.log1p(s30f/500) + 0.30*math.log1p(s90f/1500) + 0.20*math.log1p(tkf/200) + 0.20*0) sp = 0.40*math.log1p(s30f/(1*100)) rw = 0.60*lv + 0.30*sp print(f" mid={mid}, s30={s30}, s90={s90}, o90={o90}, tk={tk:.2f}, level={lv:.4f}, speed={sp:.4f}, raw={rw:.4f}") # 4. 检查 site_id 本身是否超出 integer 范围 print(f"\nsite_id={sid}, int32 max={2**31-1}, int64 max={2**63-1}") print(f"site_id > int32? {sid > 2**31-1}") print(f"site_id fits int64? {sid < 2**63-1}") # 5. 检查 dws_member_spending_power_index 的 site_id 列类型 cur.execute(""" SELECT column_name, data_type, numeric_precision FROM information_schema.columns WHERE table_schema='dws' AND table_name='dws_member_spending_power_index' AND column_name IN ('site_id', 'member_id') """) print(f"\nKey column types:") for r in cur.fetchall(): print(f" {r[0]}: {r[1]} (precision={r[2]})") conn.close() print("\n完成")