audit_wave_metadata.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #!/usr/bin/env python3
  2. """Read-only inventory of indicator-diagram files; does not fetch sample points."""
  3. from __future__ import annotations
  4. import argparse
  5. import csv
  6. import sys
  7. from pathlib import Path
  8. import pymysql
  9. BACKEND = Path(__file__).resolve().parents[1]
  10. sys.path.insert(0, str(BACKEND))
  11. from app.config import settings # noqa: E402
  12. def connect():
  13. return pymysql.connect(
  14. host=settings.db_host,
  15. port=settings.db_port,
  16. user=settings.db_user,
  17. password=settings.db_password,
  18. database=settings.db_name,
  19. charset="utf8mb4",
  20. cursorclass=pymysql.cursors.DictCursor,
  21. connect_timeout=8,
  22. read_timeout=120,
  23. )
  24. def main() -> None:
  25. parser = argparse.ArgumentParser(description="只读盘点功图文件元数据,不读取采样点")
  26. parser.add_argument("--units", nargs="+", default=["7", "8", "9"])
  27. parser.add_argument("--out", default="cache/indicator/元数据盘点.csv")
  28. args = parser.parse_args()
  29. unit_like = [f"{unit}号机组%" for unit in args.units]
  30. connection = connect()
  31. try:
  32. with connection.cursor() as cursor:
  33. cursor.execute(
  34. """
  35. SELECT
  36. CASE
  37. WHEN point_name LIKE '7号机组%%' THEN '7'
  38. WHEN point_name LIKE '8号机组%%' THEN '8'
  39. WHEN point_name LIKE '9号机组%%' THEN '9'
  40. END AS unit,
  41. DATE(sample_time) AS day,
  42. COUNT(*) AS files,
  43. SUM(CASE WHEN rpm > 0 THEN 1 ELSE 0 END) AS running_files,
  44. MIN(sample_time) AS first_time,
  45. MAX(sample_time) AS last_time
  46. FROM wave_file
  47. WHERE measurement_type = '压力'
  48. AND (point_name LIKE %s OR point_name LIKE %s OR point_name LIKE %s)
  49. GROUP BY unit, DATE(sample_time)
  50. ORDER BY unit, day
  51. """,
  52. tuple(unit_like),
  53. )
  54. daily = list(cursor.fetchall())
  55. cursor.execute(
  56. """
  57. SELECT
  58. CASE
  59. WHEN point_name LIKE '7号机组%%' THEN '7'
  60. WHEN point_name LIKE '8号机组%%' THEN '8'
  61. WHEN point_name LIKE '9号机组%%' THEN '9'
  62. END AS unit,
  63. COUNT(*) AS files,
  64. SUM(CASE WHEN rpm > 0 THEN 1 ELSE 0 END) AS running_files,
  65. COUNT(DISTINCT point_name) AS points,
  66. MIN(sample_time) AS first_time,
  67. MAX(sample_time) AS last_time
  68. FROM wave_file
  69. WHERE measurement_type = '压力'
  70. AND (point_name LIKE %s OR point_name LIKE %s OR point_name LIKE %s)
  71. GROUP BY unit
  72. ORDER BY unit
  73. """,
  74. tuple(unit_like),
  75. )
  76. totals = list(cursor.fetchall())
  77. cursor.execute(
  78. """
  79. SELECT measurement_type, COUNT(*) AS files
  80. FROM wave_file
  81. WHERE point_name LIKE %s OR point_name LIKE %s OR point_name LIKE %s
  82. GROUP BY measurement_type
  83. ORDER BY measurement_type
  84. """,
  85. tuple(unit_like),
  86. )
  87. types = list(cursor.fetchall())
  88. finally:
  89. connection.close()
  90. selected = {str(row["unit"]) for row in totals}
  91. totals = [row for row in totals if str(row["unit"]) in selected]
  92. out = Path(args.out)
  93. out.parent.mkdir(parents=True, exist_ok=True)
  94. with out.open("w", encoding="utf-8-sig", newline="") as handle:
  95. writer = csv.DictWriter(
  96. handle,
  97. fieldnames=["unit", "day", "files", "running_files", "first_time", "last_time"],
  98. )
  99. writer.writeheader()
  100. writer.writerows(daily)
  101. print("功图文件元数据盘点完成(没有读取 wave_sample_one)")
  102. print(f"按天明细:{out},共 {len(daily):,} 个有记录的机组-日期")
  103. print("\n按机组汇总:")
  104. for row in totals:
  105. print(
  106. f" {row['unit']}号:文件 {row['files']:,},运行文件 {row['running_files']:,},"
  107. f"测点 {row['points']},时间 {row['first_time']} ~ {row['last_time']}"
  108. )
  109. print("\n测量类型汇总:")
  110. for row in types:
  111. print(f" {row['measurement_type']}: {row['files']:,}")
  112. if __name__ == "__main__":
  113. main()