#!/usr/bin/env python3 # -*- coding: utf-8 -*- """audit_data_layout.py — 只读盘点 VPS 本地数据布局(DB表行数/maxdate + data/目录)。 用法: python audit_data_layout.py [BASE_DIR] 默认 BASE=C:\\sanguo_vnpy_v2 (VPS)。Mac 调试传本地路径。 只 SELECT / 遍历目录,不写任何东西。 """ import sqlite3 import sys from pathlib import Path BASE = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(r"C:\sanguo_vnpy_v2") DB = BASE / "data" / "quant_trading.db" DATA = BASE / "data" def line(s=""): print(s) # ======================== DB 表盘点 ======================== line("=" * 72) line(f"DB: {DB} exists={DB.exists()}") line("=" * 72) if DB.exists(): c = sqlite3.connect(str(DB), timeout=60) tables = [r[0] for r in c.execute( "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name")] SKIP_COUNT = {"dbbardata", "daily_baostock_full"} # 千万/亿级 COUNT 慢, 跳过 for t in tables: if t in SKIP_COUNT: line(f" {t:42s} (skip COUNT, see max below)") continue try: n = c.execute(f"SELECT COUNT(*) FROM '{t}'").fetchone()[0] except Exception as e: n = f"ERR {e}" line(f" {t:42s} {n}") # 关键表 schema + 时间范围 (大表 dbbardata/daily_baostock_full 跳过慢查询) for t in ("bs_index_constituent", "bs_adjust_factor"): try: cols = [r[1] for r in c.execute(f"PRAGMA table_info('{t}')")] if not cols: continue line("") line(f"[{t}] cols({len(cols)}): {cols}") if "symbol" in cols: nd = c.execute(f"SELECT COUNT(DISTINCT symbol) FROM '{t}'").fetchone()[0] line(f" distinct symbol = {nd}") for dc in ("date", "datetime", "trade_date"): if dc in cols: mn = c.execute(f"SELECT MIN({dc}) FROM '{t}'").fetchone()[0] mx = c.execute(f"SELECT MAX({dc}) FROM '{t}'").fetchone()[0] line(f" {dc}: {mn} ~ {mx}") break except Exception as e: line(f"[{t}] ERR {e}") c.close() # ======================== data/ 目录盘点 ======================== line("") line("=" * 72) line(f"DATA DIR: {DATA} exists={DATA.exists()}") line("=" * 72) if DATA.exists(): for sub in sorted(DATA.iterdir()): name = sub.name if name.startswith("."): continue try: if sub.is_dir(): files = list(sub.rglob("*")) n_files = sum(1 for f in files if f.is_file()) n_pq = sum(1 for f in files if f.suffix == ".parquet") n_xls = sum(1 for f in files if f.suffix in (".xls", ".xlsx")) line(f" [DIR] {name:34s} files={n_files:6d} parquet={n_pq:6d} xls={n_xls}") elif sub.is_file(): sz = sub.stat().st_size unit, val = ("GB", sz / 1024 ** 3) if sz > 1024 ** 3 else ( "MB", sz / 1024 ** 2) line(f" [FILE] {name:32s} {val:8.1f} {unit}") except Exception as e: line(f" {name} ERR {e}")