Spaces:
Sleeping
Sleeping
# File: database.py (Versi Final untuk Supabase & Hugging Face) | |
import os | |
from dotenv import load_dotenv | |
import pandas as pd | |
from sqlalchemy import create_engine, MetaData, text | |
# ----------------------------------------------------------------------------- | |
# LANGKAH 1: SETUP KONEKSI DAN METADATA | |
# ----------------------------------------------------------------------------- | |
# Muat variabel dari file .env (penting untuk pengembangan lokal) | |
load_dotenv() | |
dotenv_path = os.path.join(os.path.dirname(__file__), '.env') | |
print(f"Mencari file .env di lokasi: {dotenv_path}") | |
if os.path.exists(dotenv_path): | |
print("File .env DITEMUKAN!") | |
load_dotenv(dotenv_path=dotenv_path) | |
print("Isi DATABASE_URL setelah load:", os.getenv("DATABASE_URL")) | |
else: | |
print("PERINGATAN: File .env TIDAK DITEMUKAN di lokasi tersebut.") | |
# Ambil URL koneksi dari environment variables (atau Hugging Face Secrets) | |
DATABASE_URL = os.getenv("DATABASE_URL") | |
if not DATABASE_URL: | |
raise ValueError("DATABASE_URL tidak ditemukan. Pastikan sudah di-set di environment/secrets.") | |
# Buat engine koneksi ke database PostgreSQL | |
# echo=False bagus untuk produksi agar tidak menampilkan semua query di log | |
engine = create_engine(DATABASE_URL, echo=False) | |
# Buat objek metadata | |
metadata = MetaData() | |
# ----------------------------------------------------------------------------- | |
# LANGKAH 2: REFLEKSI TABEL DARI DATABASE | |
# ----------------------------------------------------------------------------- | |
# Daripada mendefinisikan tabel manual, kita 'mencerminkan' skema | |
# yang SUDAH ADA di database Supabase. Ini lebih aman dan fleksibel. | |
try: | |
print("Mencoba melakukan refleksi tabel dari database...") | |
metadata.reflect(bind=engine) | |
# Ambil referensi ke tabel yang sudah ada | |
users = metadata.tables['users'] | |
data_penyakit = metadata.tables['data_penyakit'] | |
detail_penyakit = metadata.tables['detail_penyakit'] | |
print("Refleksi tabel berhasil.") | |
except Exception as e: | |
print(f"Error saat melakukan refleksi tabel: {e}") | |
print("Pastikan nama tabel (users, data_penyakit, detail_penyakit) sudah benar dan ada di database Supabase.") | |
# Set ke None jika gagal agar aplikasi tidak crash saat di-import | |
users, data_penyakit, detail_penyakit = None, None, None | |
# ----------------------------------------------------------------------------- | |
# LANGKAH 3: FUNGSI-FUNGSI HELPER (JIKA ADA) | |
# ----------------------------------------------------------------------------- | |
# Contoh: Fungsi untuk mengambil data (versi yang lebih aman) | |
def ambil_data_penyakit(puskesmas, tahun): | |
""" | |
Mengambil data penyakit dari database berdasarkan filter dengan cara yang aman | |
untuk mencegah SQL Injection. | |
""" | |
# Gunakan text() dan parameter binding (:nama_param) untuk keamanan | |
query = text(""" | |
SELECT * FROM detail_penyakit | |
WHERE kode_pusk = :pusk AND tahun = :thn | |
""") | |
# Koneksi dibuka dan ditutup secara otomatis dengan 'with' | |
with engine.connect() as conn: | |
df = pd.read_sql(query, conn, params={"pusk": puskesmas, "thn": tahun}) | |
# Logika kategori tetap sama | |
def tentukan_kategori(jenis): | |
if not isinstance(jenis, str): return 'Tidak Menular' | |
menular_keywords = ['Infeksi', 'Demam', 'Diare', 'TBC', 'HIV'] | |
return 'Menular' if any(keyword.lower() in jenis.lower() for keyword in menular_keywords) else 'Tidak Menular' | |
if not df.empty: | |
df['kategori'] = df['jenis_penyakit'].apply(tentukan_kategori) | |
return df | |
# ============================================================================== | |
# SCRIPT UNTUK SETUP AWAL (TIDAK PERLU DIJALANKAN LAGI SETELAH TABEL DIBUAT) | |
# ============================================================================== | |
# Kode di bawah ini HANYA untuk membuat tabel di awal jika kamu mau. | |
# Tapi karena kita sudah buat tabel di UI Supabase, blok ini sebenarnya | |
# tidak perlu dijalankan. Saya tetap sertakan sebagai referensi. | |
def create_tables_initial_setup(): | |
print("PERINGATAN: Fungsi ini akan mencoba membuat tabel. Seharusnya tidak diperlukan jika tabel sudah dibuat di Supabase.") | |
# Definisi manual tabel (hanya untuk fungsi ini) | |
# ... (salin-tempel definisi Table(...) dari file SQLite-mu ke sini) ... | |
# ... | |
# Lalu panggil metadata.create_all(engine) | |
pass | |
# Jalankan 'python database.py' di terminal untuk memverifikasi koneksi | |
if __name__ == "__main__": | |
print("Memverifikasi koneksi dan refleksi tabel...") | |
try: | |
# 1. Verifikasi koneksi | |
with engine.connect() as connection: | |
print("=> Koneksi ke database Supabase BERHASIL!") | |
# 2. Verifikasi hasil refleksi tabel | |
# Cek apakah nama tabel ada di dalam kamus metadata.tables | |
tabel_ditemukan = { | |
'users': 'users' in metadata.tables, | |
'data_penyakit': 'data_penyakit' in metadata.tables, | |
'detail_penyakit': 'detail_penyakit' in metadata.tables | |
} | |
semua_ditemukan = all(tabel_ditemukan.values()) | |
if semua_ditemukan: | |
print("=> Refleksi tabel BERHASIL: Semua tabel (users, data_penyakit, detail_penyakit) ditemukan.") | |
else: | |
print("=> PERINGATAN: Tidak semua tabel ditemukan!") | |
for nama_tabel, status in tabel_ditemukan.items(): | |
print(f" - Tabel '{nama_tabel}': {'Ditemukan' if status else 'TIDAK DITEMUKAN'}") | |
print(" Pastikan nama tabel sudah benar sesuai di database Supabase.") | |
except Exception as e: | |
print(f"Verifikasi GAGAL: {e}") |