db_fiks
This commit is contained in:
parent
910e929394
commit
ff92f07645
|
|
@ -17,19 +17,31 @@ from sqlalchemy.exc import SQLAlchemyError
|
||||||
import pytz
|
import pytz
|
||||||
TZ_INDONESIA = pytz.timezone('Asia/Jakarta')
|
TZ_INDONESIA = pytz.timezone('Asia/Jakarta')
|
||||||
|
|
||||||
DATABASE_URL = os.environ.get('DATABASE_URL')
|
DATABASE_URL = os.environ.get('DATABASE_URL', '').strip()
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_port(value, default='3306'):
|
||||||
|
"""Return a numeric MySQL port string or a safe default."""
|
||||||
|
if value is None:
|
||||||
|
return default
|
||||||
|
|
||||||
|
value = str(value).strip()
|
||||||
|
return value if value.isdigit() else default
|
||||||
|
|
||||||
|
|
||||||
def _build_database_uri():
|
def _build_database_uri():
|
||||||
"""Build a SQLAlchemy database URI from Railway or local environment variables."""
|
"""Build a SQLAlchemy database URI from Railway or local environment variables."""
|
||||||
if DATABASE_URL:
|
if DATABASE_URL:
|
||||||
|
try:
|
||||||
url = make_url(DATABASE_URL)
|
url = make_url(DATABASE_URL)
|
||||||
if url.drivername == 'mysql':
|
if url.drivername == 'mysql':
|
||||||
url = url.set(drivername='mysql+pymysql')
|
url = url.set(drivername='mysql+pymysql')
|
||||||
return str(url)
|
return str(url)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[MYSQL] Ignoring invalid DATABASE_URL: {e}")
|
||||||
|
|
||||||
db_host = os.environ.get('DB_HOST') or os.environ.get('MYSQLHOST', 'localhost')
|
db_host = os.environ.get('DB_HOST') or os.environ.get('MYSQLHOST', 'localhost')
|
||||||
db_port = os.environ.get('DB_PORT') or os.environ.get('MYSQLPORT', '3306')
|
db_port = _normalize_port(os.environ.get('DB_PORT') or os.environ.get('MYSQLPORT'))
|
||||||
db_user = os.environ.get('DB_USER') or os.environ.get('MYSQLUSER', 'root')
|
db_user = os.environ.get('DB_USER') or os.environ.get('MYSQLUSER', 'root')
|
||||||
db_password = os.environ.get('DB_PASSWORD') or os.environ.get('MYSQLPASSWORD', '')
|
db_password = os.environ.get('DB_PASSWORD') or os.environ.get('MYSQLPASSWORD', '')
|
||||||
db_name = os.environ.get('DB_NAME') or os.environ.get('MYSQLDATABASE', 'deteksi_pmk')
|
db_name = os.environ.get('DB_NAME') or os.environ.get('MYSQLDATABASE', 'deteksi_pmk')
|
||||||
|
|
@ -43,9 +55,14 @@ def _build_database_uri():
|
||||||
DATABASE_URI = _build_database_uri()
|
DATABASE_URI = _build_database_uri()
|
||||||
|
|
||||||
# Create engine
|
# Create engine
|
||||||
engine = create_engine(DATABASE_URI, echo=False, pool_pre_ping=True)
|
try:
|
||||||
|
engine = create_engine(DATABASE_URI, echo=False, pool_pre_ping=True)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[MYSQL] Database engine unavailable: {e}")
|
||||||
|
engine = None
|
||||||
|
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
Session = sessionmaker(bind=engine)
|
Session = sessionmaker(bind=engine) if engine is not None else sessionmaker()
|
||||||
|
|
||||||
|
|
||||||
def _prediction_source_from_features(features):
|
def _prediction_source_from_features(features):
|
||||||
|
|
@ -285,6 +302,10 @@ def get_engine():
|
||||||
|
|
||||||
def init_mysql_tables():
|
def init_mysql_tables():
|
||||||
"""Initialize database tables"""
|
"""Initialize database tables"""
|
||||||
|
if engine is None:
|
||||||
|
print("[MYSQL] Skipping table initialization because database engine is unavailable")
|
||||||
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
Base.metadata.create_all(engine)
|
Base.metadata.create_all(engine)
|
||||||
migrate_diagnosis_history_schema()
|
migrate_diagnosis_history_schema()
|
||||||
|
|
@ -292,6 +313,7 @@ def init_mysql_tables():
|
||||||
seed_expert_knowledge(force=False)
|
seed_expert_knowledge(force=False)
|
||||||
sync_expert_rule_symptom_relations()
|
sync_expert_rule_symptom_relations()
|
||||||
print("Database tables initialized successfully")
|
print("Database tables initialized successfully")
|
||||||
|
return True
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
print(f"Error initializing database tables: {e}")
|
print(f"Error initializing database tables: {e}")
|
||||||
raise
|
raise
|
||||||
|
|
@ -299,6 +321,9 @@ def init_mysql_tables():
|
||||||
|
|
||||||
def migrate_diagnosis_history_schema():
|
def migrate_diagnosis_history_schema():
|
||||||
"""Remove legacy diagnosis_history columns that are no longer used."""
|
"""Remove legacy diagnosis_history columns that are no longer used."""
|
||||||
|
if engine is None:
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
inspector = inspect(engine)
|
inspector = inspect(engine)
|
||||||
table_names = inspector.get_table_names()
|
table_names = inspector.get_table_names()
|
||||||
|
|
@ -318,6 +343,9 @@ def migrate_diagnosis_history_schema():
|
||||||
|
|
||||||
def migrate_expert_rule_disease_fk():
|
def migrate_expert_rule_disease_fk():
|
||||||
"""Add the missing foreign key from expert_rules.result_disease_code to expert_diseases.code."""
|
"""Add the missing foreign key from expert_rules.result_disease_code to expert_diseases.code."""
|
||||||
|
if engine is None:
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
inspector = inspect(engine)
|
inspector = inspect(engine)
|
||||||
if 'expert_rules' not in inspector.get_table_names() or 'expert_diseases' not in inspector.get_table_names():
|
if 'expert_rules' not in inspector.get_table_names() or 'expert_diseases' not in inspector.get_table_names():
|
||||||
|
|
@ -342,6 +370,9 @@ def migrate_expert_rule_disease_fk():
|
||||||
|
|
||||||
def sync_expert_rule_symptom_relations():
|
def sync_expert_rule_symptom_relations():
|
||||||
"""Backfill the expert_rules_expert_symptoms join table from stored symptom codes."""
|
"""Backfill the expert_rules_expert_symptoms join table from stored symptom codes."""
|
||||||
|
if engine is None:
|
||||||
|
return
|
||||||
|
|
||||||
session = Session()
|
session = Session()
|
||||||
try:
|
try:
|
||||||
session.execute(expert_rules_expert_symptoms.delete())
|
session.execute(expert_rules_expert_symptoms.delete())
|
||||||
|
|
@ -377,6 +408,14 @@ def sync_expert_rule_symptom_relations():
|
||||||
|
|
||||||
def seed_expert_knowledge(force=False):
|
def seed_expert_knowledge(force=False):
|
||||||
"""Isi data default gejala, penyakit, dan aturan sistem pakar."""
|
"""Isi data default gejala, penyakit, dan aturan sistem pakar."""
|
||||||
|
if engine is None:
|
||||||
|
return {
|
||||||
|
'seeded': False,
|
||||||
|
'symptoms': 0,
|
||||||
|
'diseases': 0,
|
||||||
|
'rules': 0,
|
||||||
|
}
|
||||||
|
|
||||||
session = Session()
|
session = Session()
|
||||||
try:
|
try:
|
||||||
existing_symptoms = session.query(ExpertSymptom).count()
|
existing_symptoms = session.query(ExpertSymptom).count()
|
||||||
|
|
@ -440,6 +479,9 @@ def seed_expert_knowledge(force=False):
|
||||||
|
|
||||||
def get_expert_knowledge_mysql():
|
def get_expert_knowledge_mysql():
|
||||||
"""Ambil knowledge base sistem pakar (gejala, penyakit, aturan) dari MySQL."""
|
"""Ambil knowledge base sistem pakar (gejala, penyakit, aturan) dari MySQL."""
|
||||||
|
if engine is None:
|
||||||
|
return None
|
||||||
|
|
||||||
session = Session()
|
session = Session()
|
||||||
try:
|
try:
|
||||||
symptoms = session.query(ExpertSymptom).order_by(ExpertSymptom.display_order.asc(), ExpertSymptom.code.asc()).all()
|
symptoms = session.query(ExpertSymptom).order_by(ExpertSymptom.display_order.asc(), ExpertSymptom.code.asc()).all()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue