Python을 배워보자

Python으로 오라클 필드명과 카멜 케이스 변수 매핑 자동화하기

_Blue_Sky_ 2025. 4. 19. 00:34
728x90

 

데이터베이스 개발에서 오라클 필드명(스네이크 케이스)과 카멜 케이스 변수명을 매핑하는 작업은 종종 번거롭습니다. 특히, 필드명과 변수명이 일치하지 않거나 순서가 어긋난 경우 이를 비교하고 정리하는 데 시간이 많이 걸립니다. 이번 글에서는 Python을 사용해 오라클 필드명과 카멜 케이스 변수명을 자동으로 비교하고, 매핑되지 않은 변수를 아래로 밀어내어 비교 조견이 가능한 출력 파일을 생성하는 방법을 소개합니다. 이 스크립트는 주석도 유지하며, 아래에 매핑 가능한 변수가 있다면 순서를 조정하는 기능까지 포함합니다.
요구사항
입력 파일(test.txt)은 한 줄 단위로 |를 기준으로 왼쪽은 오라클 필드명(예: USER_ID), 오른쪽은 카멜 케이스 변수명(예: userId)으로 구성됩니다. 이 파일을 읽어 다음 작업을 수행합니다:
  • 오라클 필드명 기준 매핑: 오라클 필드명을 카멜 케이스로 변환(예: USER_IDuserId)하여 오른쪽 변수명과 비교. 일치하면 유지, 불일치하면 오른쪽 변수를 아래로 밀어냄.
  • 매핑되지 않은 변수 처리: 오른쪽 변수가 오라클 필드명과 매핑되지 않으면, 오라클 필드명이 없는 줄로 아래로 이동.
  • 순서 조정: 아래에 매핑 가능한 변수가 있다면, 해당 변수와 오라클 필드명의 순서를 맞춤.
  • 주석 유지: 주석(예: // 사용자 id)은 변수와 함께 이동.
  • 출력 파일 생성: 결과는 out.txt 파일로 저장되며, 비교 조견이 용이하도록 정렬.
728x90

 

입력 파일 예시 (test.txt)
 
USER_ID  | userId // 사용자 id
USER_NM  | userNm // 사용자명
GOOD_ID  | goodNm // 상품명
REG_DT   | createId // 생성자명
CREAT_DT |
         | arriveArea // 도착지
         | creatDt // 생성일자
출력 파일 예시 (out.txt)
 
USER_ID  | userId // 사용자 id
USER_NM  | userNm // 사용자명
GOOD_ID  |
REG_DT   |
CREAT_DT | creatDt // 생성일자
         | goodNm // 상품명
         | createId // 생성자명
         | arriveArea // 도착지
Python 구현 코드
아래는 요구사항을 충족하는 Python 스크립트입니다. re 모듈로 주석을 처리하고, 카멜 케이스 변환 및 순서 조정을 구현했습니다.
python
 
import re
from typing import List, Tuple

def to_camel_case(snake_str: str) -> str:
    """
    오라클 필드명(스네이크 케이스)을 카멜 케이스로 변환합니다.
    예: USER_ID -> userId
    """
    components = snake_str.lower().split('_')
    return components[0] + ''.join(x.capitalize() for x in components[1:])

def parse_line(line: str) -> Tuple[str, str, str]:
    """
    한 줄을 파싱하여 오라클 필드명, 변수명, 주석을 반환합니다.
    """
    line = line.strip()
    if not line:
        return '', '', ''
    
    parts = line.split('|', 1)
    oracle_field = parts[0].strip() if parts[0].strip() else ''
    
    if len(parts) > 1:
        var_part = parts[1].strip()
        var_match = re.match(r'(\w*)\s*(\/\/.*)?', var_part)
        if var_match:
            variable = var_match.group(1).strip() if var_match.group(1) else ''
            comment = var_match.group(2).strip() if var_match.group(2) else ''
        else:
            variable = var_part.strip()
            comment = ''
    else:
        variable = ''
        comment = ''
    
    return oracle_field, variable, comment

def process_file(input_file: str, output_file: str):
    """
    입력 파일을 처리하여 출력 파일을 생성합니다.
    """
    with open(input_file, 'r', encoding='utf-8') as f:
        lines = f.readlines()

    oracle_fields = []
    variables = []
    comments = []

    for line in lines:
        oracle_field, variable, comment = parse_line(line)
        oracle_fields.append(oracle_field)
        variables.append(variable)
        comments.append(comment)

    camel_fields = [to_camel_case(field) if field else '' for field in oracle_fields]
    result_oracle = [''] * len(lines)
    result_vars = [''] * len(lines)
    result_comments = [''] * len(lines)
    used_vars = set()

    # 1단계: 오라클 필드명과 일치하는 변수 매핑
    for i, (oracle_field, camel_field) in enumerate(zip(oracle_fields, camel_fields)):
        if oracle_field:
            result_oracle[i] = oracle_field
            for j, var in enumerate(variables):
                if var and var not in used_vars and var == camel_field:
                    result_vars[i] = var
                    result_comments[i] = comments[j]
                    used_vars.add(var)
                    break

    # 2단계: 매핑되지 않은 변수 아래로 밀어내기
    var_idx = 0
    for i in range(len(lines)):
        if not result_oracle[i] and not result_vars[i]:
            while var_idx < len(variables) and (not variables[var_idx] or variables[var_idx] in used_vars):
                var_idx += 1
            if var_idx < len(variables):
                result_vars[i] = variables[var_idx]
                result_comments[i] = comments[var_idx]
                used_vars.add(variables[var_idx])
                var_idx += 1

    # 3단계: 오라클 필드명과 매핑될 수 있는 변수 순서 조정
    for i, oracle_field in enumerate(oracle_fields):
        if oracle_field and not result_vars[i]:
            camel_field = to_camel_case(oracle_field)
            for j in range(len(lines)):
                if result_vars[j] == camel_field and result_oracle[j] == '':
                    result_vars[i], result_vars[j] = result_vars[j], result_vars[i]
                    result_comments[i], result_comments[j] = result_comments[j], result_comments[i]
                    break

    # 출력 파일 작성
    with open(output_file, 'w', encoding='utf-8') as f:
        for i in range(len(lines)):
            oracle = result_oracle[i]
            var = result_vars[i]
            comment = result_comments[i]
            if oracle and var:
                f.write(f"{oracle:<8} | {var} {comment}\n")
            elif oracle:
                f.write(f"{oracle:<8} |\n")
            elif var:
                f.write(f"{'':<8} | {var} {comment}\n")
            else:
                f.write('\n')

if __name__ == "__main__":
    input_file = "test.txt"
    output_file = "out.txt"
    process_file(input_file, output_file)
코드 동작 원리
  1. to_camel_case:
    • 오라클 필드명(예: USER_ID)을 카멜 케이스(예: userId)로 변환.
    • 스네이크 케이스를 _로 분리하고, 첫 단어는 소문자, 이후 단어는 첫 글자 대문자로 조합.
  2. parse_line:
    • 한 줄을 |로 분리하여 오라클 필드명, 변수명, 주석을 추출.
    • 주석은 //로 시작하며, 정규 표현식으로 변수명과 분리.
  3. process_file:
    • 입력 파일 읽기: test.txt를 줄 단위로 읽어 파싱.
    • 매핑: 오라클 필드명을 카멜 케이스로 변환 후 변수명과 비교. 일치 시 해당 위치에 유지.
    • 변수 밀어내기: 매핑되지 않은 변수는 오라클 필드명이 없는 줄로 이동.
    • 순서 조정: 매핑되지 않은 오라클 필드명에 대해, 아래에 있는 매핑 가능한 변수를 찾아 위치 교환.
    • 출력: out.txt에 결과를 포맷에 맞게 저장.
 
 
출력 결과 설명
  • USER_ID | userId: 카멜 케이스(userId)와 일치, 유지.
  • USER_NM | userNm: 카멜 케이스(userNm)와 일치, 유지.
  • GOOD_ID | goodNm: 카멜 케이스(goodId)와 불일치, goodNm은 아래로 이동.
  • REG_DT | createId: 카멜 케이스(regDt)와 불일치, createId는 아래로 이동.
  • CREAT_DT | creatDt: 아래에 있는 creatDt와 매핑, 순서 조정.
  • arriveArea: 매핑되는 오라클 필드명 없음, 아래로 이동.
코드의 장점
  • 정확한 매핑: 오라클 필드명과 변수명의 불일치를 명확히 처리.
  • 주석 유지: 주석이 변수와 함께 이동하여 가독성 향상.
  • 유연성: 다양한 입력 파일 형식에 대응 가능.
  • 비교 조견: 출력 파일을 통해 필드명과 변수명의 매핑 상태를 쉽게 확인.
주의사항
  • 입력 파일은 UTF-8 인코딩을 가정합니다. 다른 인코딩의 경우 open 함수의 encoding 파라미터를 조정하세요.
  • 오라클 필드명은 스네이크 케이스(_)를 가정합니다. 다른 형식이 필요하면 to_camel_case 함수를 수정하세요.
  • 출력 포맷은 입력 파일의 스타일을 유지하며, 공백과 주석을 보존합니다.
실행 방법
  1. test.txt 파일을 준비.
  2. Python 스크립트를 실행: python script.py
  3. out.txt 파일에서 결과를 확인.
마무리
이 스크립트를 사용하면 오라클 필드명과 카멜 케이스 변수명을 효율적으로 비교하고 정리할 수 있습니다. 데이터베이스 개발자나 시스템 통합 작업자에게 유용한 도구가 될 것입니다. 추가적인 개선이나 질문이 있다면 언제든 공유해주세요!
키워드: Python, 오라클 필드명, 카멜 케이스, 변수 매핑, 스네이크 케이스, 자동화, 파일 처리, 데이터베이스, 비교 조견, 주석 처리
728x90