remote_lock_free_ingest.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import os
  2. import sys
  3. import paramiko
  4. import dotenv
  5. import time
  6. sys.stdout.reconfigure(encoding='utf-8')
  7. sys.stderr.reconfigure(encoding='utf-8')
  8. repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  9. dotenv.load_dotenv(dotenv_path=os.path.join(repo_root, ".env"))
  10. host = os.environ.get('SERVER_HOST')
  11. user = os.environ.get('SERVER_USER')
  12. password = os.environ.get('SERVER_PASS')
  13. if password == "your_db_password_here" or not password:
  14. password = None
  15. ssh = paramiko.SSHClient()
  16. ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  17. try:
  18. ssh.connect(host, username=user, password=password, timeout=10)
  19. print("SSH Connected!")
  20. # 1. Kill any existing ingest-run container
  21. print("Killing any hung ingest containers...")
  22. ssh.exec_command("docker ps -a --filter name=food_project-ingest-run -q | xargs -r docker rm -f")
  23. # 2. Stop the Streamlit app container to guarantee no locks
  24. print("Stopping app container...")
  25. stdin, stdout, stderr = ssh.exec_command("cd food_project && docker-compose stop app")
  26. stdout.read()
  27. # 3. Restart MySQL to drop any orphaned connections or locks
  28. print("Restarting MySQL...")
  29. stdin, stdout, stderr = ssh.exec_command("cd food_project && docker-compose restart mysql")
  30. stdout.read()
  31. print("Waiting 10 seconds for MySQL to be healthy...")
  32. time.sleep(10)
  33. # 4. Run the ingestion pipeline
  34. print("Running database ingestion...")
  35. cmd = "cd food_project && docker-compose run --rm -e PYTHONIOENCODING=utf-8 ingest python -X utf8 /app/ingest_csv.py"
  36. stdin, stdout, stderr = ssh.exec_command(cmd)
  37. # Wait for completion and read output
  38. out_ing = stdout.read().decode('utf-8', errors='ignore')
  39. err_ing = stderr.read().decode('utf-8', errors='ignore')
  40. print("INGESTION STDOUT:\n", out_ing)
  41. print("INGESTION STDERR:\n", err_ing)
  42. # 5. Start Streamlit app container back up
  43. print("Starting app container back up...")
  44. stdin, stdout, stderr = ssh.exec_command("cd food_project && docker-compose start app")
  45. stdout.read()
  46. print("Ingestion flow completed successfully!")
  47. except Exception as e:
  48. print(f"Error: {e}")
  49. finally:
  50. ssh.close()