''' ____ ___ _ _ _ / ___| / _ \| | (_) |_ ___ \___ \| | | | | | | __/ _ \ ___) | |_| | |___| | || __/ |____/ \__\_\_____|_|\__\___| Script to empty (delete all data from) sensor tables in the SQLite database This script empties sensor data tables but preserves: - timestamp_table - config_table - envea_sondes_table - config_scripts_table /usr/bin/python3 /var/www/nebuleair_pro_4g/sqlite/empty_sensor_tables.py ''' import sqlite3 import sys import json def table_exists(cursor, table_name): """Check if a table exists in the database""" try: cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name=?", (table_name,)) return cursor.fetchone() is not None except sqlite3.Error as e: print(f"[ERROR] Failed to check if table '{table_name}' exists: {e}") return False def get_table_count(cursor, table_name): """Get the number of records in a table""" try: cursor.execute(f"SELECT COUNT(*) FROM {table_name}") return cursor.fetchone()[0] except sqlite3.Error as e: print(f"[WARNING] Could not get count for table '{table_name}': {e}") return 0 def empty_table(cursor, table_name): """Delete all records from a specific table""" try: # Get record count before deletion initial_count = get_table_count(cursor, table_name) if initial_count == 0: print(f"[INFO] Table '{table_name}' is already empty") return True, 0 # Delete all records cursor.execute(f"DELETE FROM {table_name}") deleted_count = cursor.rowcount print(f"[SUCCESS] Deleted {deleted_count} records from '{table_name}'") return True, deleted_count except sqlite3.Error as e: print(f"[ERROR] Failed to empty table '{table_name}': {e}") return False, 0 def main(): result = { 'success': False, 'message': '', 'tables_processed': [], 'total_deleted': 0 } try: # Connect to the SQLite database print("[INFO] Connecting to database...") conn = sqlite3.connect("/var/www/nebuleair_pro_4g/sqlite/sensors.db") cursor = conn.cursor() # Check database connection cursor.execute("SELECT sqlite_version()") version = cursor.fetchone()[0] print(f"[INFO] Connected to SQLite version: {version}") # List of sensor tables to empty (EXCLUDING timestamp_table and config tables) sensor_tables = [ "data_NPM", "data_NPM_5channels", "data_BME280", "data_envea", "data_WIND", "data_MPPT", "data_NOISE", "modem_status" ] # Tables to PRESERVE (not empty) preserved_tables = [ "timestamp_table", "config_table", "envea_sondes_table", "config_scripts_table" ] print(f"[INFO] Will empty the following sensor tables: {', '.join(sensor_tables)}") print(f"[INFO] Will preserve the following tables: {', '.join(preserved_tables)}") # Check which tables actually exist existing_tables = [] missing_tables = [] for table in sensor_tables: if table_exists(cursor, table): existing_tables.append(table) record_count = get_table_count(cursor, table) print(f"[INFO] Table '{table}' exists with {record_count} records") else: missing_tables.append(table) print(f"[WARNING] Table '{table}' does not exist - skipping") if missing_tables: print(f"[INFO] Missing tables: {', '.join(missing_tables)}") if not existing_tables: result['success'] = True result['message'] = "No sensor tables found to empty" print("[WARNING] No sensor tables found to empty!") print(json.dumps(result)) return True # Loop through existing tables and empty them successful_operations = 0 failed_operations = 0 total_deleted = 0 for table in existing_tables: success, deleted = empty_table(cursor, table) if success: successful_operations += 1 total_deleted += deleted result['tables_processed'].append({ 'name': table, 'deleted': deleted }) else: failed_operations += 1 # Commit changes print("[INFO] Committing changes...") conn.commit() print("[SUCCESS] Changes committed successfully!") # Run VACUUM to optimize database space if total_deleted > 0: print("[INFO] Running VACUUM to optimize database space...") try: cursor.execute("VACUUM") print("[SUCCESS] Database optimized successfully!") except sqlite3.Error as e: print(f"[WARNING] VACUUM failed: {e}") # Summary print(f"\n[SUMMARY]") print(f"Tables emptied successfully: {successful_operations}") print(f"Tables with errors: {failed_operations}") print(f"Tables skipped (missing): {len(missing_tables)}") print(f"Total records deleted: {total_deleted}") result['success'] = True result['message'] = f"Successfully emptied {successful_operations} sensor tables. Total records deleted: {total_deleted}" result['total_deleted'] = total_deleted if failed_operations == 0: print("[SUCCESS] All sensor tables emptied successfully!") else: result['message'] = f"Partial success: {successful_operations} tables emptied, {failed_operations} failed" print("[WARNING] Some operations failed - check logs above") # Output JSON result for web interface print("\n[JSON_RESULT]") print(json.dumps(result)) return failed_operations == 0 except sqlite3.Error as e: result['message'] = f"Database error: {e}" print(f"[ERROR] Database error: {e}") print("\n[JSON_RESULT]") print(json.dumps(result)) return False except Exception as e: result['message'] = f"Unexpected error: {e}" print(f"[ERROR] Unexpected error: {e}") print("\n[JSON_RESULT]") print(json.dumps(result)) return False finally: # Always close the database connection if 'conn' in locals(): conn.close() print("[INFO] Database connection closed") if __name__ == "__main__": success = main() sys.exit(0 if success else 1)