#!/usr/bin/env python3 """ 清理孤儿ROI配置 - 删除没有对应摄像头配置的ROI记录 - 删除关联的算法绑定记录 """ import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parent)) from core.config_sync import get_config_sync_manager def main(): print("=== Orphan ROI Cleanup Tool ===\n") config_manager = get_config_sync_manager() # 1. Get all cameras and ROIs cameras = config_manager.get_cameras() camera_ids = {c.camera_id for c in cameras} rois = config_manager.get_roi_configs(force_refresh=True) binds = config_manager.get_bindings() print(f"Current Status:") print(f" - Total cameras: {len(cameras)}") print(f" - Total ROIs: {len(rois)}") print(f" - Total bindings: {len(binds)}") # 2. Find orphan ROIs orphan_rois = [roi for roi in rois if roi.camera_id not in camera_ids] if not orphan_rois: print("\n[OK] No orphan ROIs found. Database is clean!") return print(f"\n[PROBLEM] Found {len(orphan_rois)} orphan ROIs:") for roi in orphan_rois: print(f" - ROI ID: {roi.roi_id}") print(f" Camera ID: {roi.camera_id} (MISSING)") print(f" ROI Type: {roi.roi_type if hasattr(roi, 'roi_type') else 'N/A'}") print() # 3. Find orphan bindings orphan_roi_ids = {roi.roi_id for roi in orphan_rois} orphan_binds = [b for b in binds if b.roi_id in orphan_roi_ids] if orphan_binds: print(f"Related orphan bindings: {len(orphan_binds)}") for bind in orphan_binds: print(f" - Bind ID: {bind.bind_id}") print(f" ROI ID: {bind.roi_id}") print(f" Algorithm: {bind.algo_code}") print() # 4. Ask for confirmation print("=" * 50) print("Cleanup Plan:") print(f" 1. Delete {len(orphan_rois)} orphan ROI records") print(f" 2. Delete {len(orphan_binds)} orphan binding records") print("=" * 50) response = input("\nProceed with cleanup? (yes/no): ").strip().lower() if response != 'yes': print("\n[CANCELLED] Cleanup aborted by user") return # 5. Perform cleanup print("\n[EXECUTING] Cleanup in progress...") # Initialize database manager config_manager._init_database() db_manager = config_manager._db_manager if not db_manager: print("[ERROR] Database manager not available") return deleted_rois = 0 deleted_binds = 0 # Delete orphan bindings first (foreign key constraint) for bind in orphan_binds: try: db_manager.delete_binding(bind.bind_id) deleted_binds += 1 print(f" [OK] Deleted binding: {bind.bind_id}") except Exception as e: print(f" [FAIL] Failed to delete binding {bind.bind_id}: {e}") # Delete orphan ROIs for roi in orphan_rois: try: db_manager.delete_roi(roi.roi_id) deleted_rois += 1 print(f" [OK] Deleted ROI: {roi.roi_id}") except Exception as e: print(f" [FAIL] Failed to delete ROI {roi.roi_id}: {e}") # 6. Invalidate cache config_manager.invalidate_all_cache() # 7. Summary print("\n" + "=" * 50) print("Cleanup Summary") print("=" * 50) print(f"Deleted ROIs: {deleted_rois}/{len(orphan_rois)}") print(f"Deleted bindings: {deleted_binds}/{len(orphan_binds)}") if deleted_rois == len(orphan_rois) and deleted_binds == len(orphan_binds): print("\n[SUCCESS] All orphan records cleaned up!") print("\nNext steps:") print(" 1. Restart the Edge service to apply changes") print(" 2. Warnings should disappear from logs") else: print("\n[WARNING] Some records failed to delete") print(" Please check error messages above") if __name__ == "__main__": main()