revisi_skripsi / database.py
aslasacacc's picture
The real final commit, clean start
4253e50
# 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}")