QIDNLF commited on
Commit
0dbb7a7
·
verified ·
1 Parent(s): 8ea0eb6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +16 -41
app.py CHANGED
@@ -39,9 +39,6 @@ def display_data(standard, version, selection):
39
  if main_t not in tables:
40
  main_t = tables[0]
41
 
42
- # --------------------------
43
- # 🔹 테이블 명칭 매칭 (selection이 테이블 명칭인지 확인)
44
- # --------------------------
45
  full_table_name = None
46
  pattern = re.compile(f"^{standard}[_\\s-]*{version}[_\\s-]*", re.IGNORECASE)
47
 
@@ -54,28 +51,19 @@ def display_data(standard, version, selection):
54
  full_table_name = t
55
  break
56
 
57
- # ==========================================
58
- # 🌟 부속 테이블 선택 시 (TableA, TableB_C 등)
59
- # 원본 열 구조(4열, 5열 등)를 그대로 유지
60
- # ==========================================
61
  if full_table_name and full_table_name != main_t:
62
  df = pd.read_sql(f"SELECT * FROM [{full_table_name}]", conn)
63
 
64
- # version 열 제외 및 컬럼명 정리
65
  df = df.drop(columns=[c for c in df.columns if c.lower() == "version"], errors="ignore")
66
  df.columns = [c.replace("_", " ").title() for c in df.columns]
67
 
68
- # 모든 셀에 대해 이미지 렌더링(BLOB 변환) 적용
69
  for col in df.columns:
70
  df[col] = df[col].apply(blob_to_base64_html)
71
 
72
  conn.close()
73
  return df
74
 
75
- # --------------------------
76
- # 🔹 메인 테이블 (ALL 또는 특정 Category)
77
- # 기존 규격(section, description) 유지
78
- # --------------------------
79
  cursor = conn.cursor()
80
  cursor.execute(f"PRAGMA table_info([{main_t}])")
81
  cols_info = cursor.fetchall()
@@ -103,7 +91,7 @@ def display_data(standard, version, selection):
103
  rows = cursor.fetchall()
104
  df = pd.DataFrame(rows, columns=cols)
105
 
106
- # 후처리: 메인 테이블은 가독성을 위해 2열(section, description)로 제한
107
  df.columns = [c.lower().strip() for c in df.columns]
108
  if 'section' in df.columns and 'description' in df.columns:
109
  df = df[['section', 'description']]
@@ -117,7 +105,9 @@ def display_data(standard, version, selection):
117
  except Exception as e:
118
  traceback.print_exc()
119
  return pd.DataFrame({"Error": [str(e)]})
 
120
  # --------------------------
 
121
  def blob_to_base64_html(blob_data):
122
  if blob_data is None or pd.isna(blob_data):
123
  return ""
@@ -199,21 +189,19 @@ def update_category_dd(standard, version):
199
  if main_t not in tables:
200
  main_t = tables[0] if tables else None
201
 
202
- # ==========================================
203
- # 🌟 [추가된 로직] TableA, TableB_C 등 부속 테이블을 드롭다운에 추가
204
- # ==========================================
205
  pattern = re.compile(f"^{standard}[_\\s-]*{version}[_\\s-]*", re.IGNORECASE)
206
  for t in tables:
207
  # 메인 테이블과 매핑 관련 테이블은 목록에서 제외
208
  if t == main_t or t.lower() in ['mapping_registry', 'mapping_table']:
209
  continue
210
 
211
- # 'UNR155_2101_TableA' -> 'TableA' 로 깔끔하게 자르기
212
  short_name = pattern.sub("", t).strip(" _")
213
  if short_name and short_name not in choices:
214
  choices.append(short_name)
215
  elif t not in choices:
216
  choices.append(t)
 
217
  # ==========================================
218
 
219
  if not main_t:
@@ -231,7 +219,7 @@ def update_category_dd(standard, version):
231
  for _, r in df.iterrows():
232
  chapter = str(r[ch]).strip()
233
  category = str(r[ca]).strip()
234
- # None이나 빈 값 필터링
235
  if chapter and category and chapter.lower() != 'none' and category.lower() != 'none':
236
  choices.append(f"{chapter}.{category}")
237
 
@@ -250,6 +238,7 @@ def update_category_dd(standard, version):
250
  # --------------------------
251
  # 초기화
252
  # --------------------------
 
253
  def reset_base():
254
  return gr.update(value=None), gr.update(choices=[], value=None), gr.update(choices=[], value=None)
255
 
@@ -298,6 +287,7 @@ def highlight_diff(base, comp):
298
  # --------------------------
299
  # 데이터 조회
300
  # --------------------------
 
301
  def display_data(standard, version, selection):
302
  if not all([standard, version, selection]):
303
  return pd.DataFrame({"Info": ["선택 필요"]})
@@ -320,9 +310,7 @@ def display_data(standard, version, selection):
320
  if main_t not in tables:
321
  main_t = tables[0]
322
 
323
- # --------------------------
324
- # 🔹 테이블 명칭 매칭 (selection이 테이블 명칭인지 확인)
325
- # --------------------------
326
  full_table_name = None
327
  pattern = re.compile(f"^{standard}[_\\s-]*{version}[_\\s-]*", re.IGNORECASE)
328
 
@@ -335,10 +323,6 @@ def display_data(standard, version, selection):
335
  full_table_name = t
336
  break
337
 
338
- # ==========================================
339
- # 🌟 부속 테이블 선택 시 (TableA, TableB_C 등)
340
- # 원본 열 구조(4열, 5열 등)를 그대로 유지
341
- # ==========================================
342
  if full_table_name and full_table_name != main_t:
343
  df = pd.read_sql(f"SELECT * FROM [{full_table_name}]", conn)
344
 
@@ -353,10 +337,7 @@ def display_data(standard, version, selection):
353
  conn.close()
354
  return df
355
 
356
- # --------------------------
357
- # 🔹 메인 테이블 (ALL 또는 특정 Category)
358
- # 기존 규격(section, description) 유지
359
- # --------------------------
360
  cursor = conn.cursor()
361
  cursor.execute(f"PRAGMA table_info([{main_t}])")
362
  cols_info = cursor.fetchall()
@@ -402,6 +383,7 @@ def display_data(standard, version, selection):
402
  # --------------------------
403
  # 통합 조회 (apply로 속도 최적화)
404
  # --------------------------
 
405
  def apply_diff_row(row, base_col, comp_col):
406
  """Pandas apply를 위한 Diff 연산 래퍼 함수"""
407
  base_val = str(row.get(base_col, ""))
@@ -458,9 +440,7 @@ def unified_search(bs, bv, bc, cs, cv, cc):
458
  df_b = df_base[['merge_key', 'section', 'description']].rename(columns={'section': 'sec_b', 'description': 'desc_b'})
459
  df_c = df_comp[['merge_key', 'section', 'description']].rename(columns={'section': 'sec_c', 'description': 'desc_c'})
460
 
461
- # ==========================================
462
- # 🌟 매핑 DB 가져오기 (가장 안전한 Pandas 양방향 병합)
463
- # ==========================================
464
  conn_map = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
465
 
466
  # 1. 정방향 매칭 (UI 기준 법규 == DB Base 법규)
@@ -490,9 +470,7 @@ def unified_search(bs, bv, bc, cs, cv, cc):
490
  else:
491
  df_mapping = pd.DataFrame(columns=['Base_section', 'Comp_section'])
492
 
493
- # ==========================================
494
- # 🌟 핵심 로직: 하이브리드 매핑 (명시적 + 암묵적)
495
- # ==========================================
496
  # A. 명시적 매핑 (Mapping DB에 있는 데이터)
497
  explicit_b = set(df_mapping['Base_section'].dropna())
498
  explicit_c = set(df_mapping['Comp_section'].dropna())
@@ -510,9 +488,7 @@ def unified_search(bs, bv, bc, cs, cv, cc):
510
  # C. 두 조건을 하나로 합친 브릿지(다리) 테이블
511
  bridge = pd.concat([df_mapping, df_implicit], ignore_index=True)
512
 
513
- # ==========================================
514
- # 🌟 병합(Merge) 연산 - KeyError 방지 및 원본 순서 보존
515
- # ==========================================
516
  df_b_clean = df_b.rename(columns={'merge_key': 'Base_section'})
517
  df_c_clean = df_c.rename(columns={'merge_key': 'Comp_section'})
518
 
@@ -568,7 +544,6 @@ def update_comp_standard(base_std, base_ver):
568
  try:
569
  conn = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
570
 
571
- # 🌟 핵심: 정방향 매칭과 역방향 매칭을 합침 (UNION)
572
  query = """
573
  SELECT DISTINCT Comp_std AS mapped_std
574
  FROM Mapping_registry
@@ -578,7 +553,7 @@ def update_comp_standard(base_std, base_ver):
578
  FROM Mapping_registry
579
  WHERE Comp_std=? AND Comp_ver=?
580
  """
581
- # 파라미터를 정방향용 2개, 역방향용 2개 총 4개를 넘겨줍니다.
582
  df = pd.read_sql(query, conn, params=[base_std, base_ver, base_std, base_ver])
583
  conn.close()
584
 
 
39
  if main_t not in tables:
40
  main_t = tables[0]
41
 
 
 
 
42
  full_table_name = None
43
  pattern = re.compile(f"^{standard}[_\\s-]*{version}[_\\s-]*", re.IGNORECASE)
44
 
 
51
  full_table_name = t
52
  break
53
 
54
+
 
 
 
55
  if full_table_name and full_table_name != main_t:
56
  df = pd.read_sql(f"SELECT * FROM [{full_table_name}]", conn)
57
 
 
58
  df = df.drop(columns=[c for c in df.columns if c.lower() == "version"], errors="ignore")
59
  df.columns = [c.replace("_", " ").title() for c in df.columns]
60
 
 
61
  for col in df.columns:
62
  df[col] = df[col].apply(blob_to_base64_html)
63
 
64
  conn.close()
65
  return df
66
 
 
 
 
 
67
  cursor = conn.cursor()
68
  cursor.execute(f"PRAGMA table_info([{main_t}])")
69
  cols_info = cursor.fetchall()
 
91
  rows = cursor.fetchall()
92
  df = pd.DataFrame(rows, columns=cols)
93
 
94
+
95
  df.columns = [c.lower().strip() for c in df.columns]
96
  if 'section' in df.columns and 'description' in df.columns:
97
  df = df[['section', 'description']]
 
105
  except Exception as e:
106
  traceback.print_exc()
107
  return pd.DataFrame({"Error": [str(e)]})
108
+
109
  # --------------------------
110
+
111
  def blob_to_base64_html(blob_data):
112
  if blob_data is None or pd.isna(blob_data):
113
  return ""
 
189
  if main_t not in tables:
190
  main_t = tables[0] if tables else None
191
 
192
+
 
 
193
  pattern = re.compile(f"^{standard}[_\\s-]*{version}[_\\s-]*", re.IGNORECASE)
194
  for t in tables:
195
  # 메인 테이블과 매핑 관련 테이블은 목록에서 제외
196
  if t == main_t or t.lower() in ['mapping_registry', 'mapping_table']:
197
  continue
198
 
 
199
  short_name = pattern.sub("", t).strip(" _")
200
  if short_name and short_name not in choices:
201
  choices.append(short_name)
202
  elif t not in choices:
203
  choices.append(t)
204
+
205
  # ==========================================
206
 
207
  if not main_t:
 
219
  for _, r in df.iterrows():
220
  chapter = str(r[ch]).strip()
221
  category = str(r[ca]).strip()
222
+
223
  if chapter and category and chapter.lower() != 'none' and category.lower() != 'none':
224
  choices.append(f"{chapter}.{category}")
225
 
 
238
  # --------------------------
239
  # 초기화
240
  # --------------------------
241
+
242
  def reset_base():
243
  return gr.update(value=None), gr.update(choices=[], value=None), gr.update(choices=[], value=None)
244
 
 
287
  # --------------------------
288
  # 데이터 조회
289
  # --------------------------
290
+
291
  def display_data(standard, version, selection):
292
  if not all([standard, version, selection]):
293
  return pd.DataFrame({"Info": ["선택 필요"]})
 
310
  if main_t not in tables:
311
  main_t = tables[0]
312
 
313
+
 
 
314
  full_table_name = None
315
  pattern = re.compile(f"^{standard}[_\\s-]*{version}[_\\s-]*", re.IGNORECASE)
316
 
 
323
  full_table_name = t
324
  break
325
 
 
 
 
 
326
  if full_table_name and full_table_name != main_t:
327
  df = pd.read_sql(f"SELECT * FROM [{full_table_name}]", conn)
328
 
 
337
  conn.close()
338
  return df
339
 
340
+
 
 
 
341
  cursor = conn.cursor()
342
  cursor.execute(f"PRAGMA table_info([{main_t}])")
343
  cols_info = cursor.fetchall()
 
383
  # --------------------------
384
  # 통합 조회 (apply로 속도 최적화)
385
  # --------------------------
386
+
387
  def apply_diff_row(row, base_col, comp_col):
388
  """Pandas apply를 위한 Diff 연산 래퍼 함수"""
389
  base_val = str(row.get(base_col, ""))
 
440
  df_b = df_base[['merge_key', 'section', 'description']].rename(columns={'section': 'sec_b', 'description': 'desc_b'})
441
  df_c = df_comp[['merge_key', 'section', 'description']].rename(columns={'section': 'sec_c', 'description': 'desc_c'})
442
 
443
+
 
 
444
  conn_map = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
445
 
446
  # 1. 정방향 매칭 (UI 기준 법규 == DB Base 법규)
 
470
  else:
471
  df_mapping = pd.DataFrame(columns=['Base_section', 'Comp_section'])
472
 
473
+
 
 
474
  # A. 명시적 매핑 (Mapping DB에 있는 데이터)
475
  explicit_b = set(df_mapping['Base_section'].dropna())
476
  explicit_c = set(df_mapping['Comp_section'].dropna())
 
488
  # C. 두 조건을 하나로 합친 브릿지(다리) 테이블
489
  bridge = pd.concat([df_mapping, df_implicit], ignore_index=True)
490
 
491
+
 
 
492
  df_b_clean = df_b.rename(columns={'merge_key': 'Base_section'})
493
  df_c_clean = df_c.rename(columns={'merge_key': 'Comp_section'})
494
 
 
544
  try:
545
  conn = sqlite3.connect(os.path.join(UPLOAD_DIR, "mapping.db"))
546
 
 
547
  query = """
548
  SELECT DISTINCT Comp_std AS mapped_std
549
  FROM Mapping_registry
 
553
  FROM Mapping_registry
554
  WHERE Comp_std=? AND Comp_ver=?
555
  """
556
+
557
  df = pd.read_sql(query, conn, params=[base_std, base_ver, base_std, base_ver])
558
  conn.close()
559