check_backup_import_coverage.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #!/usr/bin/env python3
  2. """Compare backup INSERT coverage vs 165 schema."""
  3. import re
  4. from collections import Counter
  5. from pathlib import Path
  6. import pymysql
  7. SQL_PATH = Path(
  8. r"D:\Projects\Ai-DOP\阿里云数据库备份\aidopdev_20260608_053527.sql\aidopdev_20260608_053527.sql"
  9. )
  10. DB = dict(
  11. host="123.60.180.165",
  12. port=3306,
  13. user="aidopremote",
  14. password="1234567890aiDOP#",
  15. database="aidopdev",
  16. charset="utf8mb4",
  17. )
  18. INSERT_RE = re.compile(
  19. r"^INSERT\s+(?:IGNORE\s+)?INTO\s+[`']?([^`'\s(]+)[`']?\s+VALUES\s",
  20. re.IGNORECASE,
  21. )
  22. def norm(name: str) -> str:
  23. return name.strip("`'\"").lower()
  24. def main() -> None:
  25. conn = pymysql.connect(**DB)
  26. cur = conn.cursor()
  27. cur.execute("SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE()")
  28. existing = {norm(r[0]) for r in cur.fetchall()}
  29. tables: Counter[str] = Counter()
  30. for line in SQL_PATH.open("r", encoding="utf-8", errors="replace"):
  31. m = INSERT_RE.match(line.strip())
  32. if m:
  33. tables[norm(m.group(1))] += 1
  34. missing = sorted(t for t in tables if t not in existing)
  35. present = sorted(t for t in tables if t in existing)
  36. print("=== Backup import coverage ===")
  37. print(f"INSERT tables in backup: {len(tables)}")
  38. print(f"Table exists on 165: {len(present)} ({sum(tables[t] for t in present)} INSERT stmts)")
  39. print(f"Table missing on 165: {len(missing)} ({sum(tables[t] for t in missing)} INSERT stmts)")
  40. if missing:
  41. print("\nMissing tables (backup has data, 165 has no table):")
  42. for t in missing:
  43. print(f" - {t} ({tables[t]} INSERT)")
  44. # tables in backup but 0 rows check not needed - just coverage
  45. conn.close()
  46. if __name__ == "__main__":
  47. main()