#!/usr/bin/env python3 """ Demo script showing different database backend options for water monitoring """ import datetime import os import sys from water_scraper_v3 import EnhancedWaterMonitorScraper def demo_sqlite(): """Demo with SQLite (local development)""" print("=" * 60) print("šŸ—„ļø SQLite Demo (Local Development)") print("=" * 60) config = {"type": "sqlite", "connection_string": "sqlite:///demo_water_sqlite.db"} try: scraper = EnhancedWaterMonitorScraper(config) # Fetch and save data print("Fetching data from API...") data = scraper.fetch_water_data() if data: print(f"āœ“ Fetched {len(data)} data points") success = scraper.save_to_database(data) if success: print("āœ“ Data saved to SQLite database") # Show latest data latest = scraper.get_latest_data(5) print(f"\nLatest 5 measurements:") for measurement in latest: print( f" • {measurement['station_code']} ({measurement['station_name_en']}): " f"{measurement['water_level']:.2f}m, {measurement['discharge']:.1f} cms" ) else: print("āœ— Failed to save data") else: print("āœ— No data fetched") except Exception as e: print(f"Error: {e}") def demo_influxdb(): """Demo with InfluxDB (requires InfluxDB running)""" print("\n" + "=" * 60) print("šŸ“Š InfluxDB Demo (Time-Series Database)") print("=" * 60) config = { "type": "influxdb", "host": "localhost", "port": 8086, "database": "water_monitoring_demo", "username": None, # Set if authentication is enabled "password": None, } try: scraper = EnhancedWaterMonitorScraper(config) if scraper.db_adapter and scraper.db_adapter.client: print("āœ“ Connected to InfluxDB") # Fetch and save data print("Fetching data from API...") data = scraper.fetch_water_data() if data: print(f"āœ“ Fetched {len(data)} data points") success = scraper.save_to_database(data) if success: print("āœ“ Data saved to InfluxDB") print("šŸ’” You can now query this data in Grafana or InfluxDB CLI") print( " Example query: SELECT * FROM water_data ORDER BY time DESC LIMIT 10" ) else: print("āœ— Failed to save data") else: print("āœ— No data fetched") else: print("āœ— Could not connect to InfluxDB") print( "šŸ’” Make sure InfluxDB is running: docker run -p 8086:8086 influxdb:1.8" ) except Exception as e: print(f"Error: {e}") print("šŸ’” InfluxDB might not be running or accessible") def demo_postgresql(): """Demo with PostgreSQL (requires PostgreSQL running)""" print("\n" + "=" * 60) print("🐘 PostgreSQL Demo (Relational Database)") print("=" * 60) config = { "type": "postgresql", "connection_string": "postgresql://postgres:password@localhost:5432/water_monitoring", } try: scraper = EnhancedWaterMonitorScraper(config) if scraper.db_adapter and scraper.db_adapter.engine: print("āœ“ Connected to PostgreSQL") # Fetch and save data print("Fetching data from API...") data = scraper.fetch_water_data() if data: print(f"āœ“ Fetched {len(data)} data points") success = scraper.save_to_database(data) if success: print("āœ“ Data saved to PostgreSQL") print("šŸ’” You can now query this data with SQL") print( " Example: SELECT * FROM water_measurements ORDER BY timestamp DESC LIMIT 10;" ) else: print("āœ— Failed to save data") else: print("āœ— No data fetched") else: print("āœ— Could not connect to PostgreSQL") print("šŸ’” Make sure PostgreSQL is running with correct credentials") except Exception as e: print(f"Error: {e}") print("šŸ’” PostgreSQL might not be running or credentials might be wrong") def demo_mysql(): """Demo with MySQL (requires MySQL running)""" print("\n" + "=" * 60) print("🐬 MySQL Demo (Relational Database)") print("=" * 60) config = { "type": "mysql", "connection_string": "mysql://root:password@localhost:3306/water_monitoring", } try: scraper = EnhancedWaterMonitorScraper(config) if scraper.db_adapter and scraper.db_adapter.engine: print("āœ“ Connected to MySQL") # Fetch and save data print("Fetching data from API...") data = scraper.fetch_water_data() if data: print(f"āœ“ Fetched {len(data)} data points") success = scraper.save_to_database(data) if success: print("āœ“ Data saved to MySQL") print("šŸ’” You can now query this data with SQL") print( " Example: SELECT * FROM water_measurements ORDER BY timestamp DESC LIMIT 10;" ) else: print("āœ— Failed to save data") else: print("āœ— No data fetched") else: print("āœ— Could not connect to MySQL") print("šŸ’” Make sure MySQL is running with correct credentials") except Exception as e: print(f"Error: {e}") print("šŸ’” MySQL might not be running or credentials might be wrong") def demo_victoriametrics(): """Demo with VictoriaMetrics (supports both local and HTTPS configurations)""" print("\n" + "=" * 60) print("⚔ VictoriaMetrics Demo (High-Performance Metrics)") print("=" * 60) # Use configuration from environment or config.py from config import Config db_config = Config.get_database_config() if db_config["type"] != "victoriametrics": # Fallback to default local configuration config = {"type": "victoriametrics", "host": "vm.newedge.house", "port": 443} else: config = db_config print(f"Connecting to: {config['host']}:{config['port']}") try: scraper = EnhancedWaterMonitorScraper(config) if scraper.db_adapter: # Test connection using the adapter's connect method if scraper.db_adapter.connect(): print("āœ“ Connected to VictoriaMetrics") # Fetch and save data print("Fetching data from API...") data = scraper.fetch_water_data() if data: print(f"āœ“ Fetched {len(data)} data points") success = scraper.save_to_database(data) if success: print("āœ“ Data saved to VictoriaMetrics") print("šŸ’” You can now query this data via Prometheus API") # Show appropriate query URL based on configuration base_url = scraper.db_adapter.base_url print(f" Example: {base_url}/api/v1/query?query=water_level") print(f" Health check: {base_url}/health") else: print("āœ— Failed to save data") else: print("āœ— No data fetched") else: print("āœ— Could not connect to VictoriaMetrics") if config["host"] == "localhost": print("šŸ’” Make sure VictoriaMetrics is running locally:") print(" docker run -p 8428:8428 victoriametrics/victoria-metrics") else: print( f"šŸ’” Check if VictoriaMetrics is accessible at {config['host']}:{config['port']}" ) print("šŸ’” Verify HTTPS configuration and network connectivity") else: print("āœ— Failed to initialize VictoriaMetrics adapter") except Exception as e: print(f"Error: {e}") print("šŸ’” Check your VictoriaMetrics configuration and network connectivity") def show_recommendations(): """Show database recommendations""" print("\n" + "=" * 60) print("šŸ† Database Recommendations") print("=" * 60) recommendations = [ { "name": "InfluxDB", "best_for": "Time-series data, Grafana dashboards", "pros": [ "Purpose-built for time-series", "Great compression", "Built-in retention", ], "cons": ["Learning curve", "Less flexible for complex queries"], "use_case": "Recommended for most water monitoring deployments", }, { "name": "PostgreSQL + TimescaleDB", "best_for": "Complex queries, existing PostgreSQL infrastructure", "pros": ["Mature ecosystem", "SQL compatibility", "ACID compliance"], "cons": ["More complex setup", "Higher resource usage"], "use_case": "Best for organizations already using PostgreSQL", }, { "name": "VictoriaMetrics", "best_for": "High-performance metrics, Prometheus compatibility", "pros": ["Extremely fast", "Low resource usage", "Better compression"], "cons": ["Newer ecosystem", "Less tooling"], "use_case": "Best for high-volume, performance-critical deployments", }, { "name": "MySQL", "best_for": "Existing MySQL infrastructure, familiar SQL", "pros": ["Familiar", "Mature", "Wide support"], "cons": ["Not optimized for time-series", "Manual optimization needed"], "use_case": "Good for organizations with existing MySQL expertise", }, ] for rec in recommendations: print(f"\nšŸ“Š {rec['name']}") print(f" Best for: {rec['best_for']}") print(f" Pros: {', '.join(rec['pros'])}") print(f" Cons: {', '.join(rec['cons'])}") print(f" šŸ’” {rec['use_case']}") def main(): """Main demo function""" print("🌊 Thailand Water Monitor - Database Backend Demo") print("This demo shows how to use different database backends") # Always run SQLite demo (no external dependencies) demo_sqlite() # Check for command line arguments to run specific demos if len(sys.argv) > 1: db_type = sys.argv[1].lower() if db_type == "influxdb": demo_influxdb() elif db_type == "postgresql": demo_postgresql() elif db_type == "mysql": demo_mysql() elif db_type == "victoriametrics": demo_victoriametrics() elif db_type == "all": demo_influxdb() demo_postgresql() demo_mysql() demo_victoriametrics() else: print(f"\nUnknown database type: {db_type}") print( "Available options: influxdb, postgresql, mysql, victoriametrics, all" ) else: print("\nšŸ’” To test other databases, run:") print(" python demo_databases.py influxdb") print(" python demo_databases.py postgresql") print(" python demo_databases.py mysql") print(" python demo_databases.py victoriametrics") print(" python demo_databases.py all") # Show recommendations show_recommendations() print("\n" + "=" * 60) print("āœ… Demo completed!") print("šŸ“– See DATABASE_DEPLOYMENT_GUIDE.md for production setup instructions") print("=" * 60) if __name__ == "__main__": main()