feat: 동물약 APC 일괄 매핑 (7개 완료)

This commit is contained in:
thug0bin 2026-02-28 11:24:16 +09:00
parent 8ee148abe4
commit dfbc6e4761
14 changed files with 814 additions and 0 deletions

View File

@ -0,0 +1,18 @@
module.exports = {
apps: [
{
name: 'pharmacy-flask',
script: 'python',
args: 'app.py',
cwd: 'c:\\Users\\청춘약국\\source\\pharmacy-pos-qr-system\\backend',
interpreter: 'none',
watch: false,
autorestart: true,
max_restarts: 10,
env: {
FLASK_ENV: 'production',
PYTHONIOENCODING: 'utf-8'
}
}
]
};

View File

@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
"""
동물약 일괄 APC 매칭 - 후보 찾기
"""
import sys, io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.path.insert(0, 'c:\\Users\\청춘약국\\source\\pharmacy-pos-qr-system\\backend')
from db.dbsetup import get_db_session
from sqlalchemy import text, create_engine
# 1. MSSQL 동물약 (APC 없는 것만)
session = get_db_session('PM_DRUG')
result = session.execute(text("""
SELECT
G.DrugCode,
G.GoodsName,
G.Saleprice,
(
SELECT TOP 1 U.CD_CD_BARCODE
FROM CD_ITEM_UNIT_MEMBER U
WHERE U.DRUGCODE = G.DrugCode
AND U.CD_CD_BARCODE LIKE '023%'
) AS APC_CODE
FROM CD_GOODS G
WHERE G.POS_BOON = '010103'
AND G.GoodsSelCode = 'B'
ORDER BY G.GoodsName
"""))
no_apc = []
for row in result:
if not row.APC_CODE:
no_apc.append({
'code': row.DrugCode,
'name': row.GoodsName,
'price': row.Saleprice
})
session.close()
print(f'=== APC 없는 동물약: {len(no_apc)}개 ===\n')
# 2. PostgreSQL에서 매칭 후보 찾기
pg = create_engine('postgresql://admin:trajet6640@192.168.0.87:5432/apdb_master').connect()
matches = []
for drug in no_apc:
name = drug['name']
# 제품명에서 검색 키워드 추출
# (판) 제거, 괄호 내용 제거
search_name = name.replace('(판)', '').split('(')[0].strip()
# PostgreSQL 검색
result = pg.execute(text("""
SELECT apc, product_name,
llm_pharm->>'사용가능 동물' as target,
llm_pharm->>'분류' as category
FROM apc
WHERE product_name ILIKE :pattern
ORDER BY LENGTH(product_name)
LIMIT 5
"""), {'pattern': f'%{search_name}%'})
candidates = list(result)
if candidates:
matches.append({
'mssql': drug,
'candidates': candidates
})
print(f'{name}')
for c in candidates[:2]:
print(f'{c.apc}: {c.product_name[:40]}... [{c.target or "?"}]')
else:
print(f'{name} - 매칭 없음')
pg.close()
print(f'\n=== 요약 ===')
print(f'APC 없는 제품: {len(no_apc)}')
print(f'매칭 후보 있음: {len(matches)}')
print(f'매칭 없음: {len(no_apc) - len(matches)}')

View File

@ -0,0 +1,75 @@
# -*- coding: utf-8 -*-
"""
확실한 매칭만 일괄 등록
"""
import sys, io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.path.insert(0, 'c:\\Users\\청춘약국\\source\\pharmacy-pos-qr-system\\backend')
from db.dbsetup import get_db_session
from sqlalchemy import text
from datetime import datetime
# 확실한 매칭 목록 (MSSQL 제품명, DrugCode, APC)
MAPPINGS = [
# 파라캅
('파라캅L(5kg이상)', 'LB000003159', '0230338510101'), # 파라캅 L 정 10정
('파라캅S(5kg이하)', 'LB000003160', '0230347110106'), # 파라캅 에스 정 10정
# 세레니아
('세레니아정16mg(개멀미약)', 'LB000003353', '0231884610109'), # 세레니아 정 16mg / 4정
('세레니아정24mg(개멀미약)', 'LB000003354', '0231884620107'), # 세레니아 정 24mg / 4정
]
session = get_db_session('PM_DRUG')
today = datetime.now().strftime('%Y%m%d')
print('=== 일괄 APC 매핑 ===\n')
for name, drugcode, apc in MAPPINGS:
# 기존 가격 조회
existing = session.execute(text("""
SELECT TOP 1 CD_MY_UNIT, CD_IN_UNIT
FROM CD_ITEM_UNIT_MEMBER
WHERE DRUGCODE = :dc
ORDER BY SN DESC
"""), {'dc': drugcode}).fetchone()
if not existing:
print(f'{name}: 기존 레코드 없음')
continue
# 이미 APC 있는지 확인
check = session.execute(text("""
SELECT 1 FROM CD_ITEM_UNIT_MEMBER
WHERE DRUGCODE = :dc AND CD_CD_BARCODE = :apc
"""), {'dc': drugcode, 'apc': apc}).fetchone()
if check:
print(f'⏭️ {name}: 이미 등록됨')
continue
# INSERT
try:
session.execute(text("""
INSERT INTO CD_ITEM_UNIT_MEMBER (
DRUGCODE, CD_CD_UNIT, CD_NM_UNIT, CD_MY_UNIT, CD_IN_UNIT,
CD_CD_BARCODE, CD_CD_POS, CHANGE_DATE
) VALUES (
:drugcode, '015', 1.0, :my_unit, :in_unit,
:barcode, '', :change_date
)
"""), {
'drugcode': drugcode,
'my_unit': existing.CD_MY_UNIT,
'in_unit': existing.CD_IN_UNIT,
'barcode': apc,
'change_date': today
})
session.commit()
print(f'{name}{apc}')
except Exception as e:
session.rollback()
print(f'{name}: {e}')
session.close()
print('\n완료!')

View File

@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
# 테스트 AI 응답 (실제 응답 시뮬레이션)
ai_response = """
, 안텔민은 개와 고양이 모두 사용 가능합니다!
**안텔민 ** - 체중 5kg 이상 반려동물용
**안텔민 뽀삐** - 체중 5kg 이하 소형 반려동물용
제품 모두 개와 고양이의 내부 기생충 구제에 효과적입니다.
"""
animal_drugs = [
{'name': '안텔민킹(5kg이상)', 'code': 'LB000003157'},
{'name': '안텔민뽀삐(5kg이하)', 'code': 'LB000003158'},
{'name': '다이로하트정M(12~22kg)', 'code': 'LB000003151'},
]
print('=== 현재 매칭 로직 테스트 ===\n')
print(f'AI 응답:\n{ai_response}\n')
print('=' * 50)
ai_response_lower = ai_response.lower()
for drug in animal_drugs:
drug_name = drug['name']
base_name = drug_name.split('(')[0].split('/')[0].strip()
# suffix 제거
original_base = base_name
for suffix in ['', '', 'L', 'M', 'S', 'XL', 'XS', 'SS', 'mini']:
if base_name.endswith(suffix):
base_name = base_name[:-len(suffix)]
base_name = base_name.strip()
matched = base_name.lower() in ai_response_lower
print(f'\n제품: {drug_name}')
print(f' 괄호 앞: {original_base}')
print(f' suffix 제거 후: {base_name}')
print(f' 매칭 결과: {"✅ 매칭됨" if matched else "❌ 매칭 안됨"}')
if not matched:
# 왜 안 됐는지 확인
print(f'"{base_name.lower()}" in 응답? {base_name.lower() in ai_response_lower}')
# 띄어쓰기 변형 체크
spaced = base_name.replace('', '').replace('뽀삐', ' 뽀삐')
print(f' → 띄어쓰기 변형 "{spaced.lower()}" in 응답? {spaced.lower() in ai_response_lower}')

View File

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
# 실제 AI 응답
ai_response = """안텔민은 개와 고양이 모두에게 사용할 수 있습니다만, 체중에 따라 복용할 용량이 다릅니다. 🐾
- **안텔민**: 5kg 이상 개와 고양이에게 복용 가능.
- **안텔민 뽀삐**: 5kg 미만 소형 반려동물에게 복용 가능.
따라서, 반려동물의 체중에 맞는 적절한 제품을 선택해야 해요! 🐶 체중을 알려주시면 구체적으로 안내해 드릴 있어요."""
animal_drugs = [
{'name': '안텔민', 'code': 'S0000001', 'apc': None},
{'name': '안텔민킹(5kg이상)', 'code': 'LB000003157', 'apc': '0230237810109'},
{'name': '안텔민뽀삐(5kg이하)', 'code': 'LB000003158', 'apc': '0230237010107'},
]
print('=== 매칭 테스트 ===\n')
print(f'AI 응답:\n{ai_response}\n')
print('=' * 50)
ai_response_lower = ai_response.lower()
ai_response_nospace = ai_response_lower.replace(' ', '')
for drug in animal_drugs:
drug_name = drug['name']
base_name = drug_name.split('(')[0].split('/')[0].strip()
for suffix in ['', '', 'L', 'M', 'S', 'XL', 'XS', 'SS', 'mini']:
if base_name.endswith(suffix):
base_name = base_name[:-len(suffix)]
base_name = base_name.strip()
base_lower = base_name.lower()
base_nospace = base_lower.replace(' ', '')
in_normal = base_lower in ai_response_lower
in_nospace = base_nospace in ai_response_nospace
matched = len(base_name) >= 2 and (in_normal or in_nospace)
print(f'\n제품: {drug_name}')
print(f' base_name: "{base_name}"')
print(f' base_nospace: "{base_nospace}"')
print(f' 일반매칭: {in_normal}')
print(f' 공백제거매칭: {in_nospace}')
print(f' 최종: {"" if matched else ""}')

View File

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
sys.path.insert(0, 'c:\\Users\\청춘약국\\source\\pharmacy-pos-qr-system\\backend')
from db.dbsetup import get_db_session
from sqlalchemy import text
# _get_animal_drugs 로직 복제
drug_session = get_db_session('PM_DRUG')
query = text("""
SELECT
G.DrugCode,
G.GoodsName,
G.Saleprice,
(
SELECT TOP 1 U.CD_CD_BARCODE
FROM CD_ITEM_UNIT_MEMBER U
WHERE U.DRUGCODE = G.DrugCode
AND U.CD_CD_BARCODE LIKE '023%'
ORDER BY U.CHANGE_DATE DESC
) AS APC_CODE
FROM CD_GOODS G
WHERE G.POS_BOON = '010103'
AND G.GoodsSelCode = 'B'
ORDER BY G.GoodsName
""")
rows = drug_session.execute(query).fetchall()
print('=== AI에 전달되는 보유 제품 목록 ===\n')
for r in rows:
apc = r.APC_CODE
rag_info = ""
if apc:
rag_info = f" [대상: 개, 고양이]" # RAG 정보 시뮬레이션
print(f"- {r.GoodsName} ({r.Saleprice:,.0f}원){rag_info}")
print('\n=== 안텔민 관련 제품만 ===')
for r in rows:
if '안텔민' in r.GoodsName:
print(f" {r.GoodsName} - APC: {r.APC_CODE}")

View File

@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
from sqlalchemy import create_engine, text
pg = create_engine('postgresql://admin:trajet6640@192.168.0.87:5432/apdb_master').connect()
# 안텔민킹 RAG 정보
apc = '0230237810109'
print(f'=== 안텔민킹 ({apc}) RAG 정보 ===\n')
result = pg.execute(text(f"""
SELECT
product_name,
llm_pharm->>'사용가능 동물' as target_animals,
llm_pharm->>'분류' as category,
llm_pharm->>'체중/부위' as dosage_weight,
llm_pharm->>'월령금기' as age_restriction
FROM apc
WHERE apc = '{apc}'
"""))
row = result.fetchone()
if row:
print(f'제품명: {row.product_name}')
print(f'사용가능 동물: {row.target_animals}')
print(f'분류: {row.category}')
print(f'체중/용량: {row.dosage_weight}')
print(f'월령금기: {row.age_restriction}')
# efficacy_effect도 확인
result2 = pg.execute(text(f"""
SELECT efficacy_effect FROM apc WHERE apc = '{apc}'
"""))
row2 = result2.fetchone()
if row2 and row2.efficacy_effect:
print(f'\n효능/효과 (원문 일부):')
print(row2.efficacy_effect[:500])
pg.close()

View File

@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
sys.path.insert(0, 'c:\\Users\\청춘약국\\source\\pharmacy-pos-qr-system\\backend')
from db.dbsetup import get_db_session
from sqlalchemy import text, create_engine
# 1. _get_animal_drugs 시뮬레이션
drug_session = get_db_session('PM_DRUG')
query = text("""
SELECT
G.DrugCode,
G.GoodsName,
G.Saleprice,
(
SELECT TOP 1 U.CD_CD_BARCODE
FROM CD_ITEM_UNIT_MEMBER U
WHERE U.DRUGCODE = G.DrugCode
AND U.CD_CD_BARCODE LIKE '023%'
ORDER BY U.CHANGE_DATE DESC
) AS APC_CODE
FROM CD_GOODS G
WHERE G.POS_BOON = '010103'
AND G.GoodsSelCode = 'B'
ORDER BY G.GoodsName
""")
rows = drug_session.execute(query).fetchall()
animal_drugs = []
for r in rows:
animal_drugs.append({
'code': r.DrugCode,
'name': r.GoodsName,
'price': float(r.Saleprice) if r.Saleprice else 0,
'apc': r.APC_CODE
})
# 2. _get_animal_drug_rag 시뮬레이션
apc_codes = [d['apc'] for d in animal_drugs if d.get('apc')]
print(f'APC 코드 목록: {apc_codes}\n')
rag_data = {}
if apc_codes:
pg = create_engine('postgresql://admin:trajet6640@192.168.0.87:5432/apdb_master').connect()
placeholders = ','.join([f"'{apc}'" for apc in apc_codes])
result = pg.execute(text(f"""
SELECT apc, product_name,
llm_pharm->>'사용가능 동물' as target_animals,
llm_pharm->>'분류' as category,
llm_pharm->>'체중/부위' as dosage_weight,
llm_pharm->>'기간/용법' as usage_period,
llm_pharm->>'월령금기' as age_restriction
FROM apc
WHERE apc IN ({placeholders})
"""))
for row in result:
rag_data[row.apc] = {
'target_animals': row.target_animals or '정보 없음',
'category': row.category or '',
'dosage_weight': row.dosage_weight or '',
'usage_period': row.usage_period or '',
'age_restriction': row.age_restriction or ''
}
pg.close()
print(f'RAG 데이터: {rag_data}\n')
# 3. available_products_text 생성
print('=== AI에 전달되는 제품 목록 (RAG 포함) ===\n')
for d in animal_drugs:
if '안텔민' in d['name']:
line = f"- {d['name']} ({d['price']:,.0f}원)"
if d.get('apc') and d['apc'] in rag_data:
info = rag_data[d['apc']]
details = []
if info.get('target_animals'):
details.append(f"대상: {info['target_animals']}")
if info.get('dosage_weight'):
details.append(f"용량: {info['dosage_weight']}")
if info.get('age_restriction'):
details.append(f"금기: {info['age_restriction']}")
if details:
line += f" [{', '.join(details)}]"
print(line)

View File

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
import sys, io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
from sqlalchemy import create_engine, text
pg = create_engine('postgresql://admin:trajet6640@192.168.0.87:5432/apdb_master').connect()
# 약국 제품 → PostgreSQL 매칭 (체중/용량 포함)
mappings = [
# (약국제품명, 검색키워드)
('제스타제(10정)', '제스타제', '10'),
('파라캅L(5kg이상)', '파라캅', 'L'),
('파라캅S(5kg이하)', '파라캅', 'S'),
('하트캅츄어블(11kg이하)', '하트캅', '11'),
('넥스가드L(15~30kg)', '넥스가드', '15'),
('넥스가드xs(2~3.5kg)', '넥스가드', '2'),
('다이로하트정M(12~22kg)', '다이로하트', '12'),
('다이로하트정S(5.6~11kg)', '다이로하트', '5.6'),
('다이로하트정SS(5.6kg이하)', '다이로하트', 'SS'),
('세레니아정16mg(개멀미약)', '세레니아', '16'),
('세레니아정24mg(개멀미약)', '세레니아', '24'),
('하트세이버츄어블M(12~22kg)', '하트세이버', '12'),
('하트세이버츄어블S(5.6~11kg)', '하트세이버', '5.6'),
('하트웜솔루션츄어블M(12~22kg)', '하트웜', '12'),
('하트웜솔루션츄어블S(11kg이하)', '하트웜', '11'),
]
print('=== 상세 매칭 검색 ===\n')
for pharm_name, keyword, size in mappings:
result = pg.execute(text("""
SELECT apc, product_name, packaging,
llm_pharm->>'사용가능 동물' as target
FROM apc
WHERE product_name ILIKE :kw
ORDER BY product_name
LIMIT 10
"""), {'kw': f'%{keyword}%'})
print(f'\n📦 {pharm_name} (검색: {keyword}, 사이즈: {size})')
for r in result:
mark = '' if size.lower() in r.product_name.lower() else ' '
print(f'{mark} {r.apc}: {r.product_name[:50]}')
pg.close()

View File

@ -0,0 +1,75 @@
# -*- coding: utf-8 -*-
import sys, io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.path.insert(0, 'c:\\Users\\청춘약국\\source\\pharmacy-pos-qr-system\\backend')
from db.dbsetup import get_db_session
from sqlalchemy import text
from datetime import datetime
session = get_db_session('PM_DRUG')
# 1. 기존 데이터에서 가격 정보 가져오기
print('1. 기존 레코드에서 가격 정보 조회...')
existing = session.execute(text("""
SELECT TOP 1 CD_MY_UNIT, CD_IN_UNIT
FROM CD_ITEM_UNIT_MEMBER
WHERE DRUGCODE = 'LB000003140'
ORDER BY SN DESC
""")).fetchone()
sale_price = existing.CD_MY_UNIT
purchase_price = existing.CD_IN_UNIT
print(f' 판매가: {sale_price:,.0f}')
print(f' 입고가: {purchase_price:,.0f}')
# 2. 오늘 날짜
today = datetime.now().strftime('%Y%m%d')
print(f'\n2. 날짜: {today}')
# 3. INSERT 실행
print('\n3. INSERT 실행...')
apc_code = '0231093520106' # 복합개시딘 10g
try:
session.execute(text("""
INSERT INTO CD_ITEM_UNIT_MEMBER (
DRUGCODE, CD_CD_UNIT, CD_NM_UNIT, CD_MY_UNIT, CD_IN_UNIT,
CD_CD_BARCODE, CD_CD_POS, CHANGE_DATE
) VALUES (
:drugcode, :unit, :nm_unit, :my_unit, :in_unit,
:barcode, :pos, :change_date
)
"""), {
'drugcode': 'LB000003140',
'unit': '015',
'nm_unit': 1.0,
'my_unit': sale_price,
'in_unit': purchase_price,
'barcode': apc_code,
'pos': '',
'change_date': today
})
session.commit()
print(f' ✅ 성공! APC {apc_code} 추가됨')
# 4. 확인
print('\n4. 결과 확인...')
result = session.execute(text("""
SELECT DRUGCODE, CD_CD_BARCODE, CD_MY_UNIT, SN
FROM CD_ITEM_UNIT_MEMBER
WHERE DRUGCODE = 'LB000003140' AND CD_CD_BARCODE = :apc
"""), {'apc': apc_code})
row = result.fetchone()
if row:
print(f' DRUGCODE: {row.DRUGCODE}')
print(f' BARCODE: {row.CD_CD_BARCODE}')
print(f' SN: {row.SN}')
except Exception as e:
session.rollback()
print(f' ❌ 실패: {e}')
session.close()

View File

@ -0,0 +1,90 @@
# -*- coding: utf-8 -*-
"""
안텔민뽀삐 APC 추가 실행 (SN 자동 생성)
"""
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
sys.path.insert(0, 'c:\\Users\\청춘약국\\source\\pharmacy-pos-qr-system\\backend')
from db.dbsetup import get_db_session
from sqlalchemy import text
from datetime import datetime
session = get_db_session('PM_DRUG')
# 1. 기존 데이터에서 가격 정보 가져오기
print('1. 기존 레코드에서 가격 정보 조회...')
existing = session.execute(text("""
SELECT TOP 1 CD_MY_UNIT, CD_IN_UNIT
FROM CD_ITEM_UNIT_MEMBER
WHERE DRUGCODE = 'LB000003158'
ORDER BY SN DESC
""")).fetchone()
sale_price = existing.CD_MY_UNIT
purchase_price = existing.CD_IN_UNIT
print(f' 판매가: {sale_price:,.0f}')
print(f' 입고가: {purchase_price:,.0f}')
# 2. 오늘 날짜
today = datetime.now().strftime('%Y%m%d')
print(f'\n2. 날짜: {today}')
# 3. INSERT 실행 (SN은 IDENTITY 자동 생성)
print('\n3. INSERT 실행...')
apc_code = '0230237010107' # 안텔민뽀삐 10정
try:
session.execute(text("""
INSERT INTO CD_ITEM_UNIT_MEMBER (
DRUGCODE,
CD_CD_UNIT,
CD_NM_UNIT,
CD_MY_UNIT,
CD_IN_UNIT,
CD_CD_BARCODE,
CD_CD_POS,
CHANGE_DATE
) VALUES (
:drugcode,
:unit,
:nm_unit,
:my_unit,
:in_unit,
:barcode,
:pos,
:change_date
)
"""), {
'drugcode': 'LB000003158',
'unit': '015',
'nm_unit': 1.0,
'my_unit': sale_price,
'in_unit': purchase_price,
'barcode': apc_code,
'pos': '',
'change_date': today
})
session.commit()
print(f' ✅ 성공! APC {apc_code} 추가됨')
# 4. 확인
print('\n4. 결과 확인...')
result = session.execute(text("""
SELECT * FROM CD_ITEM_UNIT_MEMBER
WHERE DRUGCODE = 'LB000003158' AND CD_CD_BARCODE = :apc
"""), {'apc': apc_code})
row = result.fetchone()
if row:
print(' --- 추가된 레코드 ---')
for col in result.keys():
print(f' {col}: {getattr(row, col)}')
except Exception as e:
session.rollback()
print(f' ❌ 실패: {e}')
session.close()

View File

@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
"""
안텔민뽀삐 APC 추가 준비 스크립트
- CD_ITEM_UNIT_MEMBER 구조 확인
- 안텔민킹 레코드 참고
- INSERT 쿼리 생성 (실행 )
"""
import sys
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
sys.path.insert(0, 'c:\\Users\\청춘약국\\source\\pharmacy-pos-qr-system\\backend')
from db.dbsetup import get_db_session
from sqlalchemy import text
session = get_db_session('PM_DRUG')
print('=' * 60)
print('1. CD_ITEM_UNIT_MEMBER 테이블 구조')
print('=' * 60)
result = session.execute(text("""
SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, CHARACTER_MAXIMUM_LENGTH
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'CD_ITEM_UNIT_MEMBER'
ORDER BY ORDINAL_POSITION
"""))
for r in result:
nullable = 'NULL' if r.IS_NULLABLE == 'YES' else 'NOT NULL'
length = f'({r.CHARACTER_MAXIMUM_LENGTH})' if r.CHARACTER_MAXIMUM_LENGTH else ''
print(f' {r.COLUMN_NAME}: {r.DATA_TYPE}{length} {nullable}')
print('\n' + '=' * 60)
print('2. 안텔민킹 APC 레코드 (참고용)')
print('=' * 60)
result = session.execute(text("""
SELECT * FROM CD_ITEM_UNIT_MEMBER
WHERE DRUGCODE = 'LB000003157'
AND CD_CD_BARCODE LIKE '023%'
"""))
row = result.fetchone()
if row:
cols = result.keys()
for col in cols:
val = getattr(row, col)
print(f' {col}: {val}')
print('\n' + '=' * 60)
print('3. 안텔민뽀삐 현재 레코드')
print('=' * 60)
result2 = session.execute(text("""
SELECT * FROM CD_ITEM_UNIT_MEMBER
WHERE DRUGCODE = 'LB000003158'
ORDER BY SN DESC
"""))
rows = list(result2)
print(f'{len(rows)}개 레코드')
for row in rows[:3]:
print(f'\n --- SN: {row.SN} ---')
cols = result2.keys()
for col in cols:
val = getattr(row, col)
print(f' {col}: {val}')
print('\n' + '=' * 60)
print('4. 다음 SN 값 확인')
print('=' * 60)
result3 = session.execute(text("SELECT MAX(SN) as max_sn FROM CD_ITEM_UNIT_MEMBER"))
max_sn = result3.fetchone().max_sn
print(f' 현재 MAX(SN): {max_sn}')
print(f' 다음 SN: {max_sn + 1}')
session.close()
print('\n' + '=' * 60)
print('5. PostgreSQL에서 안텔민뽀삐 APC 확인')
print('=' * 60)
from sqlalchemy import create_engine
pg = create_engine('postgresql://admin:trajet6640@192.168.0.87:5432/apdb_master').connect()
result4 = pg.execute(text("""
SELECT apc, product_name
FROM apc
WHERE product_name ILIKE '%안텔민%뽀삐%' OR product_name ILIKE '%안텔민%5kg%이하%'
ORDER BY apc
"""))
for r in result4:
print(f' APC: {r.apc}')
print(f' 제품명: {r.product_name}')
print()
pg.close()

View File

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
import sys, io, json
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
from sqlalchemy import create_engine, text
pg = create_engine('postgresql://admin:trajet6640@192.168.0.87:5432/apdb_master').connect()
# 안텔민킹 llm_pharm 전체 확인
result = pg.execute(text("""
SELECT product_name, llm_pharm FROM apc WHERE apc = '0230237810109'
"""))
row = result.fetchone()
print('=== 안텔민킹 llm_pharm 전체 키 ===\n')
data = row.llm_pharm
for k in sorted(data.keys()):
val = str(data[k])
if len(val) > 60:
val = val[:60] + '...'
print(f' {k}: {val}')
# 동물약 전체 개수
print('\n=== PostgreSQL 동물약 전체 개수 ===')
result2 = pg.execute(text("SELECT COUNT(*) FROM apc"))
print(f' 전체: {result2.fetchone()[0]}')
pg.close()

View File

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
import sys, io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.path.insert(0, 'c:\\Users\\청춘약국\\source\\pharmacy-pos-qr-system\\backend')
from db.dbsetup import get_db_session
from sqlalchemy import text
session = get_db_session('PM_DRUG')
print('1. 현재 상태 확인...')
result = session.execute(text("""
SELECT DrugCode, GoodsName, POS_BOON
FROM CD_GOODS
WHERE DrugCode = 'LB000003140'
"""))
row = result.fetchone()
print(f' {row.GoodsName}: POS_BOON = {row.POS_BOON}')
print('\n2. POS_BOON을 동물약(010103)으로 업데이트...')
try:
session.execute(text("""
UPDATE CD_GOODS
SET POS_BOON = '010103'
WHERE DrugCode = 'LB000003140'
"""))
session.commit()
print(' ✅ 성공!')
# 확인
result2 = session.execute(text("""
SELECT DrugCode, GoodsName, POS_BOON
FROM CD_GOODS
WHERE DrugCode = 'LB000003140'
"""))
row2 = result2.fetchone()
print(f' {row2.GoodsName}: POS_BOON = {row2.POS_BOON}')
except Exception as e:
session.rollback()
print(f' ❌ 실패: {e}')
session.close()