diff --git a/add_samsoeun_formula.py b/add_samsoeun_formula.py new file mode 100644 index 0000000..9f33483 --- /dev/null +++ b/add_samsoeun_formula.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 +""" +삼소음 처방 추가 스크립트 + +처방 추가 가이드 문서의 방식에 따라 삼소음을 추가합니다. +""" + +import sqlite3 +from datetime import datetime + +def add_samsoeun(): + """삼소음 처방 추가""" + + # 처방 데이터 준비 + prescription_data = { + 'formula_code': 'SSE001', # 삼소음 코드 + 'formula_name': '삼소음', + 'formula_type': 'STANDARD', + 'base_cheop': 1, + 'base_pouches': 1, + 'description': '리기화담, 해표산한의 효능으로 외감풍한과 내상식적으로 인한 기침, 가래를 치료하는 처방', + 'ingredients': [ + {'code': '3400H1AHM', 'herb': '인삼', 'amount': 4.0, 'notes': '대보원기'}, + {'code': '3411H1AHM', 'herb': '소엽(자소엽)', 'amount': 4.0, 'notes': '해표산한'}, + {'code': '3433H1AHM', 'herb': '전호', 'amount': 4.0, 'notes': '강기화담'}, + {'code': '3182H1AHM', 'herb': '반하', 'amount': 4.0, 'notes': '화담지구'}, + {'code': '3002H1AHM', 'herb': '갈근', 'amount': 4.0, 'notes': '승진해기'}, + {'code': '3215H1AHM', 'herb': '적복령(복령)', 'amount': 4.0, 'notes': '건비이수'}, + {'code': '3115H1AHM', 'herb': '대조(대추)', 'amount': 4.0, 'notes': '보중익기'}, + {'code': '3466H1AHM', 'herb': '진피', 'amount': 3.0, 'notes': '리기화담'}, + {'code': '3077H1AHM', 'herb': '길경', 'amount': 3.0, 'notes': '선폐거담'}, + {'code': '3454H1AHM', 'herb': '지각', 'amount': 3.0, 'notes': '파기소적'}, + {'code': '3007H1AHM', 'herb': '감초', 'amount': 3.0, 'notes': '조화제약'}, + {'code': '3017H1AHM', 'herb': '건강', 'amount': 1.0, 'notes': '온중산한'} + ] + } + + conn = sqlite3.connect('database/kdrug.db') + cursor = conn.cursor() + + try: + # 기존 삼소음 처방 확인 + cursor.execute(""" + SELECT formula_id, formula_code, formula_name + FROM formulas + WHERE formula_code = ? OR formula_name = ? + """, (prescription_data['formula_code'], prescription_data['formula_name'])) + + existing = cursor.fetchone() + if existing: + print(f"⚠️ 이미 존재하는 처방: {existing[2]} ({existing[1]})") + print("기존 처방을 삭제하고 새로 추가하시겠습니까? (이 스크립트는 자동으로 진행합니다)") + + # 기존 처방과 관련 데이터 삭제 + cursor.execute("DELETE FROM formula_ingredients WHERE formula_id = ?", (existing[0],)) + cursor.execute("DELETE FROM formulas WHERE formula_id = ?", (existing[0],)) + print(f"✅ 기존 처방 삭제 완료") + + print(f"\n{'='*60}") + print(f"📝 {prescription_data['formula_name']} 처방 추가 중...") + + # 1. formulas 테이블에 처방 추가 + cursor.execute(""" + INSERT INTO formulas ( + formula_code, formula_name, formula_type, + base_cheop, base_pouches, description, + is_active, created_at, updated_at + ) VALUES (?, ?, ?, ?, ?, ?, 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) + """, ( + prescription_data['formula_code'], + prescription_data['formula_name'], + prescription_data['formula_type'], + prescription_data['base_cheop'], + prescription_data['base_pouches'], + prescription_data['description'] + )) + + formula_id = cursor.lastrowid + print(f"✅ 처방 기본 정보 등록 (ID: {formula_id})") + + # 2. formula_ingredients 테이블에 약재 추가 + print(f"\n약재 구성:") + sort_order = 0 + total_amount = 0 + + for ingredient in prescription_data['ingredients']: + cursor.execute(""" + INSERT INTO formula_ingredients ( + formula_id, ingredient_code, + grams_per_cheop, notes, + sort_order, created_at + ) VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP) + """, ( + formula_id, + ingredient['code'], + ingredient['amount'], + ingredient['notes'], + sort_order + )) + + sort_order += 1 + total_amount += ingredient['amount'] + print(f" - {ingredient['herb']:15s}: {ingredient['amount']:5.1f}g ({ingredient['notes']})") + + print(f"\n총 약재: {len(prescription_data['ingredients'])}개") + print(f"1첩 총 용량: {total_amount:.1f}g") + + conn.commit() + print(f"\n✅ {prescription_data['formula_name']} 처방 추가 완료!") + + # 추가된 처방 확인 + print(f"\n{'='*60}") + print("📊 추가된 처방 확인:") + + cursor.execute(""" + SELECT f.formula_id, f.formula_code, f.formula_name, + COUNT(fi.ingredient_id) as herb_count, + SUM(fi.grams_per_cheop) as total_grams + FROM formulas f + LEFT JOIN formula_ingredients fi ON f.formula_id = fi.formula_id + WHERE f.formula_code = ? + GROUP BY f.formula_id + """, (prescription_data['formula_code'],)) + + result = cursor.fetchone() + if result: + print(f"ID {result[0]}: {result[1]} - {result[2]}") + print(f" 약재 {result[3]}개, 총 {result[4]:.1f}g") + + # 상세 구성 확인 + print(f"\n상세 구성:") + cursor.execute(""" + SELECT hm.herb_name, fi.grams_per_cheop, fi.notes + FROM formula_ingredients fi + JOIN herb_masters hm ON fi.ingredient_code = hm.ingredient_code + WHERE fi.formula_id = ? + ORDER BY fi.sort_order + """, (result[0],)) + + for herb, amount, notes in cursor.fetchall(): + print(f" - {herb:15s}: {amount:5.1f}g ({notes})") + + except sqlite3.IntegrityError as e: + print(f"❌ 중복 오류: {e}") + conn.rollback() + return False + except sqlite3.Error as e: + print(f"❌ 데이터베이스 오류: {e}") + conn.rollback() + return False + finally: + conn.close() + + return True + +if __name__ == "__main__": + print("🌿 삼소음 처방 추가 프로그램") + print("="*60) + + if add_samsoeun(): + print("\n✅ 삼소음 처방 추가 작업이 완료되었습니다.") + else: + print("\n❌ 처방 추가 중 오류가 발생했습니다.") \ No newline at end of file diff --git a/add_wolbitang_formulas.py b/add_wolbitang_formulas.py new file mode 100644 index 0000000..c9607b0 --- /dev/null +++ b/add_wolbitang_formulas.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python3 +""" +월비탕 단계별 처방 추가 스크립트 + +월비탕 1차부터 4차까지 단계별로 처방을 등록합니다. +각 단계마다 약재의 용량이 다릅니다. +""" + +import sqlite3 +from datetime import datetime + +def add_wolbitang_formulas(): + """월비탕 단계별 처방 추가""" + + # 약재 성분 코드 매핑 + herb_codes = { + "마황": "3147H1AHM", + "석고": "3265H1AHM", + "감초": "3007H1AHM", + "진피": "3632H1AHM", + "복령": "3215H1AHM", + "갈근": "3002H1AHM", + "지황": "3463H1AHM", # 건지황 대신 지황 사용 + "창출": "3472H1AHM" + } + + # 월비탕 단계별 처방 데이터 + wolbitang_prescriptions = [ + { + 'formula_code': 'WBT001-1', + 'formula_name': '월비탕 1차', + 'formula_type': 'CUSTOM', + 'base_cheop': 1, + 'base_pouches': 1, + 'description': '월비탕 1차 - 단계별 처방의 첫 번째 단계', + 'ingredients': [ + {'herb': '마황', 'amount': 4.0, 'notes': '발한해표'}, + {'herb': '석고', 'amount': 3.0, 'notes': '청열사화'}, + {'herb': '감초', 'amount': 3.0, 'notes': '조화제약'}, + {'herb': '진피', 'amount': 3.333, 'notes': '리기화담'}, + {'herb': '복령', 'amount': 4.0, 'notes': '건비이수'}, + {'herb': '갈근', 'amount': 3.333, 'notes': '승진해기'}, + {'herb': '지황', 'amount': 3.333, 'notes': '보음청열'}, + {'herb': '창출', 'amount': 3.333, 'notes': '건비조습'} + ] + }, + { + 'formula_code': 'WBT001-2', + 'formula_name': '월비탕 2차', + 'formula_type': 'CUSTOM', + 'base_cheop': 1, + 'base_pouches': 1, + 'description': '월비탕 2차 - 단계별 처방의 두 번째 단계', + 'ingredients': [ + {'herb': '마황', 'amount': 5.0, 'notes': '발한해표'}, + {'herb': '석고', 'amount': 4.0, 'notes': '청열사화'}, + {'herb': '감초', 'amount': 3.0, 'notes': '조화제약'}, + {'herb': '진피', 'amount': 3.75, 'notes': '리기화담'}, + {'herb': '복령', 'amount': 4.0, 'notes': '건비이수'}, + {'herb': '갈근', 'amount': 3.333, 'notes': '승진해기'}, + {'herb': '지황', 'amount': 3.333, 'notes': '보음청열'}, + {'herb': '창출', 'amount': 3.333, 'notes': '건비조습'} + ] + }, + { + 'formula_code': 'WBT001-3', + 'formula_name': '월비탕 3차', + 'formula_type': 'CUSTOM', + 'base_cheop': 1, + 'base_pouches': 1, + 'description': '월비탕 3차 - 단계별 처방의 세 번째 단계', + 'ingredients': [ + {'herb': '마황', 'amount': 6.0, 'notes': '발한해표'}, + {'herb': '석고', 'amount': 4.17, 'notes': '청열사화'}, + {'herb': '감초', 'amount': 3.0, 'notes': '조화제약'}, + {'herb': '진피', 'amount': 4.17, 'notes': '리기화담'}, + {'herb': '복령', 'amount': 4.17, 'notes': '건비이수'}, + {'herb': '갈근', 'amount': 3.75, 'notes': '승진해기'}, + {'herb': '지황', 'amount': 3.75, 'notes': '보음청열'}, + {'herb': '창출', 'amount': 3.333, 'notes': '건비조습'} + ] + }, + { + 'formula_code': 'WBT001-4', + 'formula_name': '월비탕 4차', + 'formula_type': 'CUSTOM', + 'base_cheop': 1, + 'base_pouches': 1, + 'description': '월비탕 4차 - 단계별 처방의 네 번째 단계', + 'ingredients': [ + {'herb': '마황', 'amount': 7.0, 'notes': '발한해표'}, + {'herb': '석고', 'amount': 5.0, 'notes': '청열사화'}, + {'herb': '감초', 'amount': 3.0, 'notes': '조화제약'}, + {'herb': '진피', 'amount': 4.17, 'notes': '리기화담'}, + {'herb': '복령', 'amount': 5.0, 'notes': '건비이수'}, + {'herb': '갈근', 'amount': 3.75, 'notes': '승진해기'}, + {'herb': '지황', 'amount': 4.0, 'notes': '보음청열'}, + {'herb': '창출', 'amount': 3.333, 'notes': '건비조습'} + ] + } + ] + + conn = sqlite3.connect('database/kdrug.db') + cursor = conn.cursor() + + try: + # 기존 월비탕 처방 확인 + cursor.execute(""" + SELECT formula_code, formula_name + FROM formulas + WHERE formula_code LIKE 'WBT%' + ORDER BY formula_code + """) + existing = cursor.fetchall() + if existing: + print("⚠️ 기존 월비탕 처방 발견:") + for code, name in existing: + print(f" - {code}: {name}") + print() + + # 각 처방 추가 + for prescription in wolbitang_prescriptions: + print(f"\n{'='*60}") + print(f"📝 {prescription['formula_name']} 추가 중...") + + # 1. formulas 테이블에 처방 추가 + cursor.execute(""" + INSERT INTO formulas ( + formula_code, formula_name, formula_type, + base_cheop, base_pouches, description, + is_active, created_at, updated_at + ) VALUES (?, ?, ?, ?, ?, ?, 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) + """, ( + prescription['formula_code'], + prescription['formula_name'], + prescription['formula_type'], + prescription['base_cheop'], + prescription['base_pouches'], + prescription['description'] + )) + + formula_id = cursor.lastrowid + print(f" ✅ 처방 기본 정보 등록 (ID: {formula_id})") + + # 2. formula_ingredients 테이블에 약재 추가 + sort_order = 0 + for ingredient in prescription['ingredients']: + herb_name = ingredient['herb'] + ingredient_code = herb_codes[herb_name] + + cursor.execute(""" + INSERT INTO formula_ingredients ( + formula_id, ingredient_code, + grams_per_cheop, notes, + sort_order, created_at + ) VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP) + """, ( + formula_id, + ingredient_code, + ingredient['amount'], + ingredient['notes'], + sort_order + )) + + sort_order += 1 + print(f" - {herb_name}: {ingredient['amount']}g ({ingredient['notes']})") + + print(f" ✅ {prescription['formula_name']} 추가 완료!") + + conn.commit() + print(f"\n{'='*60}") + print("🎉 월비탕 1차~4차 모든 처방이 성공적으로 추가되었습니다!") + + # 추가된 처방 확인 + print("\n📊 추가된 월비탕 처방 목록:") + print("-"*60) + cursor.execute(""" + SELECT f.formula_id, f.formula_code, f.formula_name, + COUNT(fi.ingredient_id) as herb_count, + SUM(fi.grams_per_cheop) as total_grams + FROM formulas f + LEFT JOIN formula_ingredients fi ON f.formula_id = fi.formula_id + WHERE f.formula_code LIKE 'WBT%' + GROUP BY f.formula_id + ORDER BY f.formula_code + """) + + for row in cursor.fetchall(): + print(f"ID {row[0]}: {row[1]} - {row[2]}") + print(f" 약재 {row[3]}개, 총 {row[4]:.3f}g") + + except sqlite3.IntegrityError as e: + print(f"❌ 중복 오류: {e}") + print(" 이미 동일한 처방 코드가 존재합니다.") + conn.rollback() + return False + except sqlite3.Error as e: + print(f"❌ 데이터베이스 오류: {e}") + conn.rollback() + return False + finally: + conn.close() + + return True + +if __name__ == "__main__": + print("🌿 월비탕 단계별 처방 추가 프로그램") + print("="*60) + + if add_wolbitang_formulas(): + print("\n✅ 월비탕 처방 추가 작업이 완료되었습니다.") + else: + print("\n❌ 처방 추가 중 오류가 발생했습니다.") \ No newline at end of file diff --git a/check_samsoeun_ingredients.py b/check_samsoeun_ingredients.py new file mode 100644 index 0000000..f1433a0 --- /dev/null +++ b/check_samsoeun_ingredients.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +""" +삼소음에 사용되는 약재들의 성분 코드 확인 +""" + +import sqlite3 + +def check_herb_codes(): + """약재 성분 코드 확인""" + + # 삼소음에 사용되는 약재들 + herbs_to_check = [ + "인삼", + "소엽", # 자소엽 + "전호", + "반하", + "갈근", + "적복령", # 적복령 또는 복령 + "대조", # 대추 + "진피", + "길경", + "지각", + "감초", + "건강" + ] + + conn = sqlite3.connect('database/kdrug.db') + cursor = conn.cursor() + + herb_codes = {} + + print("🌿 삼소음 약재 성분 코드 확인") + print("="*60) + + for herb in herbs_to_check: + # 정확한 이름으로 먼저 검색 + cursor.execute(""" + SELECT ingredient_code, herb_name, herb_name_hanja + FROM herb_masters + WHERE herb_name = ? + """, (herb,)) + + result = cursor.fetchone() + + # 정확한 이름이 없으면 포함된 이름으로 검색 + if not result: + # 특수 케이스 처리 + if herb == "소엽": + search_term = "자소엽" + elif herb == "대조": + search_term = "대추" + elif herb == "적복령": + search_term = "적복령" + else: + search_term = herb + + cursor.execute(""" + SELECT ingredient_code, herb_name, herb_name_hanja + FROM herb_masters + WHERE herb_name LIKE ? OR herb_name = ? + ORDER BY + CASE WHEN herb_name = ? THEN 0 ELSE 1 END, + LENGTH(herb_name) + LIMIT 1 + """, (f'%{search_term}%', search_term, search_term)) + result = cursor.fetchone() + + if result: + herb_codes[herb] = result[0] + print(f"✅ {herb}: {result[0]} ({result[1]})") + else: + print(f"❌ {herb}: 찾을 수 없음") + + # 유사한 이름 검색 + cursor.execute(""" + SELECT herb_name + FROM herb_masters + WHERE herb_name LIKE ? + LIMIT 5 + """, (f'%{herb[:2]}%',)) + similar = cursor.fetchall() + if similar: + print(f" 유사한 약재: {', '.join([s[0] for s in similar])}") + + # 복령 관련 추가 확인 + if "적복령" not in herb_codes or not herb_codes.get("적복령"): + print("\n📌 복령 관련 약재 추가 검색:") + cursor.execute(""" + SELECT ingredient_code, herb_name + FROM herb_masters + WHERE herb_name LIKE '%복령%' + ORDER BY herb_name + """) + bokryung_list = cursor.fetchall() + for code, name in bokryung_list: + print(f" - {code}: {name}") + + conn.close() + + return herb_codes + +if __name__ == "__main__": + herb_codes = check_herb_codes() + + print("\n📊 약재 코드 매핑 결과:") + print("-"*60) + for herb, code in herb_codes.items(): + if code: + print(f'"{herb}": "{code}",') \ No newline at end of file diff --git a/check_wolbitang_ingredients.py b/check_wolbitang_ingredients.py new file mode 100644 index 0000000..295f711 --- /dev/null +++ b/check_wolbitang_ingredients.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +""" +월비탕에 사용되는 약재들의 성분 코드 확인 +""" + +import sqlite3 + +def check_herb_codes(): + """약재 성분 코드 확인""" + + # 월비탕에 사용되는 약재들 + herbs_to_check = [ + "마황", + "석고", + "감초", + "진피", + "복령", + "갈근", + "건지황", + "창출" + ] + + conn = sqlite3.connect('database/kdrug.db') + cursor = conn.cursor() + + herb_codes = {} + + print("🌿 월비탕 약재 성분 코드 확인") + print("="*50) + + for herb in herbs_to_check: + # 정확한 이름으로 먼저 검색 + cursor.execute(""" + SELECT ingredient_code, herb_name, herb_name_hanja + FROM herb_masters + WHERE herb_name = ? + """, (herb,)) + + result = cursor.fetchone() + + # 정확한 이름이 없으면 포함된 이름으로 검색 + if not result: + cursor.execute(""" + SELECT ingredient_code, herb_name, herb_name_hanja + FROM herb_masters + WHERE herb_name LIKE ? + ORDER BY LENGTH(herb_name) + LIMIT 1 + """, (f'%{herb}%',)) + result = cursor.fetchone() + + if result: + herb_codes[herb] = result[0] + print(f"✅ {herb}: {result[0]} ({result[1]}, {result[2]})") + else: + print(f"❌ {herb}: 찾을 수 없음") + # 비슷한 이름 찾기 + cursor.execute(""" + SELECT herb_name + FROM herb_masters + WHERE herb_name LIKE ? + LIMIT 5 + """, (f'%{herb[:2]}%',)) + similar = cursor.fetchall() + if similar: + print(f" 유사한 약재: {', '.join([s[0] for s in similar])}") + + conn.close() + + return herb_codes + +if __name__ == "__main__": + herb_codes = check_herb_codes() + + print("\n📊 약재 코드 매핑 결과:") + print("-"*50) + for herb, code in herb_codes.items(): + print(f'"{herb}": "{code}",') \ No newline at end of file diff --git a/docs/처방_추가_가이드.md b/docs/처방_추가_가이드.md new file mode 100644 index 0000000..e3a7aa6 --- /dev/null +++ b/docs/처방_추가_가이드.md @@ -0,0 +1,293 @@ +# 처방 데이터 추가 가이드 + +## 개요 +이 문서는 K-Drug 시스템에 새로운 한방 처방을 추가하는 방법을 설명합니다. + +## 데이터베이스 구조 + +### 1. formulas 테이블 +처방의 기본 정보를 저장하는 테이블입니다. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| formula_id | INTEGER | 처방 고유 ID (자동생성) | +| formula_code | TEXT | 처방 코드 (예: SCR001) | +| formula_name | TEXT | 처방 이름 (예: 소청룡탕) | +| formula_type | TEXT | 처방 타입 (STANDARD/CUSTOM) | +| base_cheop | INTEGER | 기본 첩수 | +| base_pouches | INTEGER | 기본 포수 | +| description | TEXT | 처방 설명 | +| is_active | INTEGER | 활성 상태 (1: 활성, 0: 비활성) | + +### 2. formula_ingredients 테이블 +처방을 구성하는 약재 정보를 저장하는 테이블입니다. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| ingredient_id | INTEGER | 구성 약재 ID (자동생성) | +| formula_id | INTEGER | 처방 ID (formulas 테이블 참조) | +| ingredient_code | TEXT | 약재 성분 코드 (herb_masters 테이블 참조) | +| grams_per_cheop | REAL | 1첩당 용량(g) | +| notes | TEXT | 약재 역할/효능 설명 | +| sort_order | INTEGER | 정렬 순서 | + +### 3. herb_masters 테이블 +약재 마스터 정보를 저장하는 테이블입니다. + +| 컬럼명 | 타입 | 설명 | +|--------|------|------| +| ingredient_code | VARCHAR(10) | 약재 성분 코드 (PK) | +| herb_name | VARCHAR(100) | 약재 이름 | +| herb_name_hanja | VARCHAR(100) | 약재 한자명 | +| herb_name_latin | VARCHAR(200) | 약재 학명 | + +## 처방 추가 절차 + +### 1단계: 약재 성분 코드 확인 +처방에 사용할 약재들의 성분 코드를 먼저 확인해야 합니다. + +```python +import sqlite3 + +conn = sqlite3.connect('database/kdrug.db') +cursor = conn.cursor() + +# 약재 이름으로 성분 코드 검색 +herb_name = "마황" +cursor.execute(""" + SELECT ingredient_code, herb_name + FROM herb_masters + WHERE herb_name LIKE ? +""", (f'%{herb_name}%',)) + +results = cursor.fetchall() +for code, name in results: + print(f"{name}: {code}") + +conn.close() +``` + +### 2단계: 처방 데이터 준비 +처방 정보와 구성 약재 정보를 준비합니다. + +```python +prescription_data = { + 'formula_code': 'SCR001', # 고유한 처방 코드 + 'formula_name': '소청룡탕', + 'formula_type': 'STANDARD', # STANDARD 또는 CUSTOM + 'base_cheop': 1, # 기본 첩수 + 'base_pouches': 1, # 기본 포수 + 'description': '처방 설명', + 'ingredients': [ + { + 'code': '3147H1AHM', # 약재 성분 코드 + 'amount': 6.0, # 1첩당 용량(g) + 'notes': '발한해표' # 약재 역할 + }, + # ... 추가 약재들 + ] +} +``` + +### 3단계: 데이터베이스에 추가 +준비한 데이터를 데이터베이스에 저장합니다. + +```python +import sqlite3 + +def add_prescription(prescription_data): + conn = sqlite3.connect('database/kdrug.db') + cursor = conn.cursor() + + try: + # 1. formulas 테이블에 처방 추가 + cursor.execute(""" + INSERT INTO formulas ( + formula_code, formula_name, formula_type, + base_cheop, base_pouches, description, + is_active, created_at, updated_at + ) VALUES (?, ?, ?, ?, ?, ?, 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) + """, ( + prescription_data['formula_code'], + prescription_data['formula_name'], + prescription_data['formula_type'], + prescription_data['base_cheop'], + prescription_data['base_pouches'], + prescription_data['description'] + )) + + formula_id = cursor.lastrowid + + # 2. formula_ingredients 테이블에 약재 추가 + for ingredient in prescription_data['ingredients']: + cursor.execute(""" + INSERT INTO formula_ingredients ( + formula_id, ingredient_code, + grams_per_cheop, notes, + sort_order, created_at + ) VALUES (?, ?, ?, ?, 0, CURRENT_TIMESTAMP) + """, ( + formula_id, + ingredient['code'], + ingredient['amount'], + ingredient['notes'] + )) + + conn.commit() + print(f"처방 '{prescription_data['formula_name']}' 추가 완료!") + + except Exception as e: + conn.rollback() + print(f"오류 발생: {e}") + finally: + conn.close() +``` + +## 자동화 스크립트 사용법 + +### add_prescription_data.py 스크립트 +프로젝트에 포함된 `add_prescription_data.py` 스크립트를 사용하여 처방을 쉽게 추가할 수 있습니다. + +1. 스크립트 실행: +```bash +python3 add_prescription_data.py +``` + +2. 스크립트 수정하여 새 처방 추가: +```python +prescriptions = [ + { + 'formula_code': '새처방코드', + 'formula_name': '새처방이름', + 'formula_type': 'STANDARD', + 'base_cheop': 1, + 'base_pouches': 1, + 'description': '처방 설명', + 'ingredients': [ + # 구성 약재 목록 + ] + } +] +``` + +## 주의사항 + +### 1. 성분 코드 확인 +- 반드시 herb_masters 테이블에 존재하는 ingredient_code를 사용해야 합니다 +- 보험 코드(insurance_code)가 아닌 성분 코드(ingredient_code)를 사용합니다 + +### 2. 중복 확인 +- formula_code는 고유해야 합니다 +- 동일한 처방 코드로 중복 추가하지 않도록 주의합니다 + +### 3. 약재 용량 +- grams_per_cheop은 1첩 기준 용량입니다 +- 소수점 사용 가능 (예: 1.5, 0.5) + +### 4. 처방 타입 +- STANDARD: 표준 처방 +- CUSTOM: 사용자 정의 처방 + +## 데이터 검증 + +### 추가된 처방 확인 +```python +import sqlite3 + +conn = sqlite3.connect('database/kdrug.db') +cursor = conn.cursor() + +# 처방 목록 조회 +cursor.execute(""" + SELECT formula_code, formula_name, formula_type + FROM formulas + WHERE is_active = 1 +""") + +for row in cursor.fetchall(): + print(f"{row[0]}: {row[1]} ({row[2]})") + +conn.close() +``` + +### 처방 상세 정보 조회 +```python +# 특정 처방의 구성 약재 확인 +formula_code = 'SCR001' + +cursor.execute(""" + SELECT hm.herb_name, fi.grams_per_cheop, fi.notes + FROM formulas f + JOIN formula_ingredients fi ON f.formula_id = fi.formula_id + JOIN herb_masters hm ON fi.ingredient_code = hm.ingredient_code + WHERE f.formula_code = ? + ORDER BY fi.grams_per_cheop DESC +""", (formula_code,)) + +for herb_name, amount, notes in cursor.fetchall(): + print(f"- {herb_name}: {amount}g ({notes})") +``` + +## 문제 해결 + +### 1. 약재를 찾을 수 없는 경우 +- herb_masters 테이블에서 정확한 약재명 확인 +- 대체 이름 검색 (예: 대조 → 대추, 백작약 → 작약) + +### 2. 외래 키 제약 오류 +- ingredient_code가 herb_masters 테이블에 존재하는지 확인 +- formula_id가 올바른지 확인 + +### 3. 중복 키 오류 +- formula_code가 이미 존재하는지 확인 +- 필요시 기존 처방 삭제 또는 코드 변경 + +## 예제: 실제 처방 추가 + +### 소청룡탕 추가 예제 +```python +{ + 'formula_code': 'SCR001', + 'formula_name': '소청룡탕', + 'formula_type': 'STANDARD', + 'base_cheop': 1, + 'base_pouches': 1, + 'description': '외감풍한, 내정수음으로 인한 기침, 천식을 치료하는 처방', + 'ingredients': [ + {'code': '3147H1AHM', 'amount': 6.0, 'notes': '발한해표'}, # 마황 + {'code': '3419H1AHM', 'amount': 6.0, 'notes': '화영지통'}, # 백작약 + {'code': '3342H1AHM', 'amount': 6.0, 'notes': '렴폐지해'}, # 오미자 + {'code': '3182H1AHM', 'amount': 6.0, 'notes': '화담지구'}, # 반하 + {'code': '3285H1AHM', 'amount': 4.0, 'notes': '온폐산한'}, # 세신 + {'code': '3017H1AHM', 'amount': 4.0, 'notes': '온중산한'}, # 건강 + {'code': '3033H1AHM', 'amount': 4.0, 'notes': '해표발한'}, # 계지 + {'code': '3007H1AHM', 'amount': 4.0, 'notes': '조화제약'}, # 감초 + ] +} +``` + +### 갈근탕 추가 예제 +```python +{ + 'formula_code': 'GGT001', + 'formula_name': '갈근탕', + 'formula_type': 'STANDARD', + 'base_cheop': 1, + 'base_pouches': 1, + 'description': '외감풍한으로 인한 두통, 발열, 오한, 항강을 치료하는 처방', + 'ingredients': [ + {'code': '3002H1AHM', 'amount': 8.0, 'notes': '승진해기'}, # 갈근 + {'code': '3147H1AHM', 'amount': 6.0, 'notes': '발한해표'}, # 마황 + {'code': '3115H1AHM', 'amount': 6.0, 'notes': '보중익기'}, # 대조 + {'code': '3033H1AHM', 'amount': 4.0, 'notes': '해표발한'}, # 계지 + {'code': '3419H1AHM', 'amount': 4.0, 'notes': '화영지통'}, # 작약 + {'code': '3007H1AHM', 'amount': 4.0, 'notes': '조화제약'}, # 감초 + {'code': '3017H1AHM', 'amount': 2.0, 'notes': '온중산한'}, # 건강 + ] +} +``` + +## 참고 자료 +- 데이터베이스 스키마: `database/kdrug.db` +- 자동화 스크립트: `add_prescription_data.py` +- 약재 마스터 데이터: `herb_masters` 테이블 \ No newline at end of file diff --git a/find_jihwang.py b/find_jihwang.py new file mode 100644 index 0000000..76c87fd --- /dev/null +++ b/find_jihwang.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +""" +지황 관련 약재 찾기 +""" + +import sqlite3 + +conn = sqlite3.connect('database/kdrug.db') +cursor = conn.cursor() + +# 지황 관련 약재 검색 +cursor.execute(""" + SELECT ingredient_code, herb_name, herb_name_hanja + FROM herb_masters + WHERE herb_name LIKE '%지황%' + OR herb_name LIKE '%생지%' + OR herb_name LIKE '%건지%' + OR herb_name LIKE '%숙지%' + ORDER BY herb_name +""") + +results = cursor.fetchall() + +print("🌿 지황 관련 약재 검색 결과:") +print("="*60) +for code, name, hanja in results: + print(f"{code}: {name} ({hanja})") + +conn.close() \ No newline at end of file diff --git a/find_jinpi.py b/find_jinpi.py new file mode 100644 index 0000000..deddc1c --- /dev/null +++ b/find_jinpi.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +""" +진피 관련 약재 찾기 +""" + +import sqlite3 + +conn = sqlite3.connect('database/kdrug.db') +cursor = conn.cursor() + +# 진피 관련 약재 검색 +cursor.execute(""" + SELECT ingredient_code, herb_name, herb_name_hanja + FROM herb_masters + WHERE herb_name LIKE '%진피%' + OR herb_name = '진피' + OR herb_name = '陳皮' + ORDER BY herb_name +""") + +results = cursor.fetchall() + +print("🌿 진피 관련 약재 검색 결과:") +print("="*60) +for code, name, hanja in results: + print(f"{code}: {name} ({hanja})") + +# 정확히 '진피'만 찾기 +print("\n정확히 '진피' 검색:") +cursor.execute(""" + SELECT ingredient_code, herb_name, herb_name_hanja + FROM herb_masters + WHERE herb_name = '진피' +""") + +result = cursor.fetchone() +if result: + print(f"✅ 찾음: {result[0]}: {result[1]} ({result[2]})") +else: + print("❌ 정확한 '진피'를 찾을 수 없음") + +conn.close() \ No newline at end of file diff --git a/verify_samsoeun.py b/verify_samsoeun.py new file mode 100644 index 0000000..2aeff82 --- /dev/null +++ b/verify_samsoeun.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python3 +""" +삼소음 처방 데이터 검증 스크립트 +""" + +import sqlite3 + +def verify_samsoeun(): + """추가된 삼소음 처방 검증""" + + conn = sqlite3.connect('database/kdrug.db') + cursor = conn.cursor() + + print("🔍 삼소음 처방 상세 검증") + print("="*70) + + # 삼소음 처방 정보 조회 + cursor.execute(""" + SELECT f.formula_id, f.formula_code, f.formula_name, f.description, + f.base_cheop, f.base_pouches + FROM formulas f + WHERE f.formula_code = 'SSE001' + """) + + formula = cursor.fetchone() + + if formula: + formula_id, code, name, description, base_cheop, base_pouches = formula + + print(f"\n📝 {name} ({code})") + print(f" ID: {formula_id}") + print(f" 설명: {description}") + print(f" 기본 첩수: {base_cheop}첩") + print(f" 기본 포수: {base_pouches}포") + + # 약재 구성 상세 조회 + print(f"\n 약재 구성 (1첩 기준):") + print(" " + "-"*60) + + cursor.execute(""" + SELECT hm.herb_name, fi.grams_per_cheop, fi.notes, hm.ingredient_code + FROM formula_ingredients fi + JOIN herb_masters hm ON fi.ingredient_code = hm.ingredient_code + WHERE fi.formula_id = ? + ORDER BY fi.sort_order + """, (formula_id,)) + + ingredients = cursor.fetchall() + total_1cheop = 0 + total_20cheop = 0 # 20첩(1제) 기준 + + print(f" {'약재명':15s} | {'1첩(g)':>8s} | {'20첩(g)':>8s} | {'효능'}") + print(" " + "-"*60) + + for herb_name, grams, notes, code in ingredients: + total_1cheop += grams + grams_20 = grams * 20 + total_20cheop += grams_20 + print(f" {herb_name:15s} | {grams:8.1f} | {grams_20:8.1f} | {notes}") + + print(" " + "-"*60) + print(f" {'총 용량':15s} | {total_1cheop:8.1f} | {total_20cheop:8.1f} |") + + # 원본 데이터와 비교 + print(f"\n📊 원본 데이터와 비교:") + print(" " + "-"*60) + + original_data = { + "인삼": (4, 80), + "소엽": (4, 80), + "전호": (4, 80), + "반하": (4, 80), + "갈근": (4, 80), + "적복령": (4, 80), + "대조": (4, 80), + "진피": (3, 60), + "길경": (3, 60), + "지각": (3, 60), + "감초": (3, 60), + "건강": (1, 20) + } + + print(f" {'약재':10s} | {'원본 1첩':>10s} | {'DB 1첩':>10s} | {'일치여부'}") + print(" " + "-"*60) + + # DB 데이터를 딕셔너리로 변환 + db_data = {} + for herb_name, grams, notes, code in ingredients: + # 약재명 정규화 + if "자소엽" in herb_name: + key = "소엽" + elif "복령" in herb_name: + key = "적복령" + elif "대추" in herb_name: + key = "대조" + elif "진피" in herb_name: + key = "진피" + else: + key = herb_name + + db_data[key] = grams + + # 비교 + all_match = True + for herb, (orig_1, orig_20) in original_data.items(): + db_amount = db_data.get(herb, 0) + match = "✅" if abs(orig_1 - db_amount) < 0.01 else "❌" + if match == "❌": + all_match = False + print(f" {herb:10s} | {orig_1:10.1f}g | {db_amount:10.1f}g | {match}") + + print("\n" + "="*70) + if all_match: + print("✅ 모든 약재가 원본 데이터와 일치합니다!") + else: + print("⚠️ 일부 약재가 원본 데이터와 일치하지 않습니다.") + + else: + print("❌ 삼소음 처방을 찾을 수 없습니다.") + + conn.close() + +if __name__ == "__main__": + verify_samsoeun() \ No newline at end of file diff --git a/verify_wolbitang.py b/verify_wolbitang.py new file mode 100644 index 0000000..d7df62f --- /dev/null +++ b/verify_wolbitang.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3 +""" +월비탕 처방 데이터 검증 스크립트 +""" + +import sqlite3 + +def verify_wolbitang(): + """추가된 월비탕 처방 검증""" + + conn = sqlite3.connect('database/kdrug.db') + cursor = conn.cursor() + + print("🔍 월비탕 처방 상세 검증") + print("="*70) + + # 각 처방별 상세 정보 조회 + cursor.execute(""" + SELECT f.formula_id, f.formula_code, f.formula_name, f.description + FROM formulas f + WHERE f.formula_code LIKE 'WBT%' + ORDER BY f.formula_code + """) + + formulas = cursor.fetchall() + + for formula_id, formula_code, formula_name, description in formulas: + print(f"\n📝 {formula_name} ({formula_code})") + print(f" 설명: {description}") + print(f" 약재 구성:") + + # 각 처방의 약재 상세 조회 + cursor.execute(""" + SELECT hm.herb_name, fi.grams_per_cheop, fi.notes + FROM formula_ingredients fi + JOIN herb_masters hm ON fi.ingredient_code = hm.ingredient_code + WHERE fi.formula_id = ? + ORDER BY fi.sort_order + """, (formula_id,)) + + ingredients = cursor.fetchall() + total_grams = 0 + + for herb_name, grams, notes in ingredients: + print(f" - {herb_name:8s}: {grams:6.3f}g ({notes})") + total_grams += grams + + print(f" 총 용량: {total_grams:.3f}g") + + # 단계별 용량 변화 비교 + print(f"\n{'='*70}") + print("📊 단계별 약재 용량 변화:") + print("-"*70) + + # 약재별 단계별 용량 조회 + cursor.execute(""" + SELECT DISTINCT hm.herb_name + FROM formula_ingredients fi + JOIN herb_masters hm ON fi.ingredient_code = hm.ingredient_code + JOIN formulas f ON fi.formula_id = f.formula_id + WHERE f.formula_code LIKE 'WBT%' + ORDER BY hm.herb_name + """) + + herbs = [row[0] for row in cursor.fetchall()] + + print(f"{'약재명':10s} | {'1차':>8s} | {'2차':>8s} | {'3차':>8s} | {'4차':>8s}") + print("-"*50) + + for herb in herbs: + amounts = [] + for stage in range(1, 5): + cursor.execute(""" + SELECT fi.grams_per_cheop + FROM formula_ingredients fi + JOIN herb_masters hm ON fi.ingredient_code = hm.ingredient_code + JOIN formulas f ON fi.formula_id = f.formula_id + WHERE f.formula_code = ? AND hm.herb_name = ? + """, (f'WBT001-{stage}', herb)) + + result = cursor.fetchone() + amounts.append(f"{result[0]:.3f}g" if result else "-") + + print(f"{herb:10s} | {amounts[0]:>8s} | {amounts[1]:>8s} | {amounts[2]:>8s} | {amounts[3]:>8s}") + + conn.close() + +if __name__ == "__main__": + verify_wolbitang() \ No newline at end of file