본문 바로가기
SK Shieldus Rookies 19th/인프라 활용을 위한 파이썬

[SK shieldus Rookies 19기][Python, SQL] - 실습 3

by En_Geon 2024. 3. 20.

1. CLI 기반의 CRUD 프로그램

 

출력 예시

==========================
메뉴
--------------------------
Q : 종료         ⇒ 프로그램을 종료
I : 등록           ⇒ 등록 화면으로 이동
S : 검색          ⇒ 검색 화면으로 이동
==========================
메뉴를 선택하세요 >>>


==========================
회원 등록
--------------------------
이름 : 홍길동
나이 : 23
이메일 : hong@test.com
==========================
Y : 등록 / N : 취소

Y → members 테이블에 입력한 내용을 저장 → 등록했습니다. 출력 후 메뉴 화면으로 이동
N → 메뉴 화면으로 이동
 

==========================
회원 검색
--------------------------
이름 : 길동
==========================
Y : 검색 / N : 취소

Y → members 테이블에 like 검색 → 검색 결과 화면으로 이동
N → 메뉴 화면으로 이동


==========================
회원 검색 결과 (OO건)
--------------------------
1 : 홍길동                     ⇐ 검색 결과를 회원아이디 : 회원이름 형식으로 나열
2 : 고길동                         검색 결과가 없는 경우 "일치하는 결과 없음" 출력
3 : 신길동
==========================
번호 : 상세 조회 / N : 취소

번호(회원 아이디) → 회원 상세 조회 화면으로 이동
N → 메뉴 화면으로 이동


==========================
회원 상세 조회
--------------------------
아이디 : 1
이름 : 홍길동
나이 : 23
이메일 : hong@test.com
==========================
U : 수정 D : 삭제 / Y : 메뉴로 이동

D → 해당 회원 삭제 후 "삭제했습니다" 메시지를 출력하고 메뉴 화면으로 이동
U → 수정 화면으로 이동
N → 메뉴 화면으로 이동


==========================
회원 수정
--------------------------
아이디 : 1                                ⇐ 회원 정보를 보여주고,
이름 : 홍길동
나이 : 23
이메일 : hong@test.com
==========================
나이 : 43
이메일 : gildong@test.com
수정할까요? (Y : 수정 / N : 메뉴로 이동)

Y → 나이와 이메일을 입력받아서 수정 후 "수정했습니다." 메시지를 출력하고
메뉴 화면으로 이동
N → 메뉴 화면으로 이동
 
 
회원 등록 및 수정 시 이름, 나이, 이메일의 형식을 정규식을 이용해서 검증 후 등록, 수정 처리해야 함

 

위 출력 예시처럼 구현되는 프로그램을 작성하는 실습이다. 

이 프로그램을 시작했을 때는 막막했다. 어떻게 작성해야 하는지 몰랐지만 하나하나 코드가 지나가는 순서대로 짚어보면서 이해하려고 노력했다. 내 방식대로 최대한 이해하는데 1.5일 정도 걸린 것 같다.

 

실습은 코드로 대체한다.

 

2. 실습 코드

 

더보기

 

import pymysql
import re

def print_double_line() :
    print(f'{'=' * 26}')
    
def print_single_line() :
    print(f"{'-' * 26}")

def print_title(title) :
    print()
    print_double_line()
    print(title)
    print_single_line()

def ans_check(message, user_input) :
    while True:
        i = input(message).upper()
        if i in user_input :
            return i
        else:
            print("잘못된 입력입니다. 확인 후 다시 입력해 주세요.")

def print_main_menu():
    print_title('메뉴')
    print('I : 회원 등록')
    print('S : 회원 검색')
    print('Q : 종료')
    print_double_line()

def main() :
    print_main_menu()

    menu = ans_check('메뉴를 입력하세요 : ', ("I", "S", "Q"))
    if menu == 'I' :
        add_member()
    elif menu == 'S' :
        search_member()
    else :
        print("종료합니다.")

def add_name_check(name):
    return bool(re.match('^[가-힣]+$', name))

def add_age_check(age) :
    return bool(re.match(r'^([1-9]|[1-9][0-9]|1[0-4][0-9]|150)$', age))

def add_email_check(email) :
    return bool(re.match(r'^[a-zA-Z0-9_]+@[a-zA-Z0-9]+\.[a-zA-Z]{2,}$', email))

def input_check(message, pattern_name) :    
    while True :
        user_input = input(message)
        if pattern_name(user_input) :
            return user_input
        else :
            print("입력이 잘못되었습니다. 다시 입력하세요")


def add_member():
    print_title('회원 등록')

    name = input_check("이름 : ", add_name_check)
    age = input_check("나이 : ", add_age_check)
    email = input_check('이메일 : ', add_email_check)
    
    print_single_line()

    YN = ans_check('등록하시겠습니까? (Y : 등록 / N : 취소) :', ('Y', "N"))
    if YN == 'Y' :
        query = "INSERT INTO members (member_name, member_age, member_email) values (%s, %s, %s)"

        try:
            with pymysql.connect(host="localhost", port=3306, user="springboot", passwd="qwert12345",
                                db="sampledb", cursorclass=pymysql.cursors.DictCursor) as conn:
                
                curr = conn.cursor()
                count = curr.execute(query, (name, age, email))
                if count == 1:
                    print("회원 정보를 정상적으로 등록했습니다.")
                    conn.commit()
                    yn = ans_check('추가 등록하시겠습니까? (Y : 등록 / N : 메인 메뉴) :', ('Y', "N"))
                    if yn == 'Y' :
                        add_member()
                    else :
                        main()
                else:
                    print("회원 정보를 등록하는데 실패했습니다.")
                    conn.rollback()
                    main()
        except pymysql.MySQLError as e:
            print(e) 
    else :
        YN =ans_check("회원 등록을 취소했습니다.\n다시 등록하시겠습니까? (Y : 등록 / N : 메인 메뉴) : ", ('Y', 'N'))
        if YN == 'Y' :
            add_member()
        else :
            print("회원 등록을 취소합니다.")
            main()


def search_member() :
    print_title("회원 검색")
    name = input_check("이름 : ", add_name_check)
    print_double_line()

    YN = ans_check('검색하시겠습니까? (Y : 검색 / N : 취소) : ', ('Y', "N"))
    if YN == 'Y' :
        query = "SELECT * FROM members WHERE member_name like %s"
        try:
            with pymysql.connect(host="localhost", port=3306, user="springboot", passwd="qwert12345",
                                db="sampledb", cursorclass=pymysql.cursors.DictCursor, autocommit=True) as conn:
                
                
                curr = conn.cursor()
                count = curr.execute(query, ('%'+name+'%',))
                results = curr.fetchall()
                print_title(f'회원 검색 결과 (총 {count}건)')

                if count == 0 :
                    print("일치하는 결과가 없습니다. 다시 검색해 주세요.")
                    search_member()
                else :
                    id_nums = []
                    for result in results :
                        id_nums.append(str(result['member_id']))
                        print(f"{result['member_id']} : {result['member_name']}")
                    print_single_line()
                    id_nums.append('N')            
                    detail_member(id_nums)               
        except pymysql.MySQLError as e:
            print(e) 
    else :
        YN =ans_check("회원 검색을 취소했습니다.\n다시 검색하시겠습니까? (Y : 검색 / N : 메인 메뉴) : ", ('Y', 'N'))
        if YN == 'Y' :
            search_member()
        else :
            print("회원 검색을 취소합니다.")
            main()


def detail_member(id_nums) :
    id_num = ans_check("회원 상세 조회 하시겠습니까? (번호 : 상세 조회 / N : 메인 메뉴) : ", id_nums)
    if id_num == 'N' :
        print('상세 조회를 취소합니다.')
        main()
    else :
        print_title('회원 상세 조회')
        query = "SELECT * FROM members WHERE member_id = %s"
        try:
            with pymysql.connect(host="localhost", port=3306, user="springboot", passwd="qwert12345",
                                db="sampledb", cursorclass=pymysql.cursors.DictCursor, autocommit=True) as conn:
                
                curr = conn.cursor()
                curr.execute(query, (id_num,))
                member = curr.fetchone()

                print(f"ID : {member['member_id']}")
                print(f"이름 : {member['member_name']}")
                print(f"나이 : {member['member_age']}")
                print(f"이메일 : {member['member_email']}")
                    
                print_double_line()
                
                UDN = ans_check('어떤 작업을 하시겠습니까? (U : 수정 / D : 삭제 / N : 메인 메뉴) : ', 
                                ('U', 'D','N'))
                if UDN == 'U' :
                    update_member(member['member_id'])
                elif UDN == 'D' :
                    delete_member(member['member_id'])
                else :
                    main()
        except pymysql.MySQLError as e:
            print(e)


def update_member(id) :
    print_title('회원 수정')
    query = "SELECT * FROM members WHERE member_id = %s"
    try:
        with pymysql.connect(host="localhost", port=3306, user="springboot", passwd="qwert12345",
                            db="sampledb", cursorclass=pymysql.cursors.DictCursor) as conn:
            
            curr = conn.cursor()
            curr.execute(query, (id,))
            member = curr.fetchone()

            print(f"ID : {member['member_id']}")
            print(f"이름 : {member['member_name']}")
            print(f"나이 : {member['member_age']}")
            print(f"이메일 : {member['member_email']}")
            print_double_line()

            age = input_check("나이 : ", add_age_check)
            email = input_check('이메일 : ', add_email_check)
            YN = ans_check("수정할까요? (Y : 수정 / N : 취소) : ", ("Y", "N"))
        
            if YN == 'N' :
                YSN = ans_check(f"{member['member_name']} 수정을 취소했습니다.\n"
                               f"{member['member_name']} 다시 수정하시려면 Y, 다른 검색 하시려면 S를 입력하세요."
                               " (Y : 수정 / S : 검색 / N : 메인 메뉴) : ",
                               ("Y", 'S', "N"))
                if YSN == "Y" :
                    update_member(id)
                elif YSN == 'S' :
                    print("수정 취소 합니다.")
                    search_member()
                else :
                    print("수정 취소 합니다.")
                    main()
            else :
                query = "UPDATE members SET member_age = %s, member_email = %s WHERE member_id = %s"
                count = curr.execute(query, (age, email, id))
                if count == 1 :
                    print("회원 정보를 정상적으로 수정했습니다.")
                    conn.commit()
                    main()
                else:
                    print("회원 정보를 등록하는데 실패했습니다.")
                    conn.rollback()
                    main()
    except pymysql.MySQLError as e:
            print(e)


def delete_member(id) :
    YN = ans_check("회원 정보를 삭제하시겠습니까? (Y : 삭제 / N : 취소) : ", ('Y', 'N'))
    if YN== 'N' :
        print("회원 정보 삭제를 취소했습니다.")
        main()
    else :
        query = 'DELETE FROM members WHERE member_id = %s'
        try:
            with pymysql.connect(host="localhost", port=3306, user="springboot", passwd="qwert12345",
                            db="sampledb", cursorclass=pymysql.cursors.DictCursor) as conn:
            
                curr = conn.cursor()
                count = curr.execute(query, (id,))

                if count == 1 :
                    print("회원 정보를 정상적으로 삭제했습니다.")
                    conn.commit()
                    main()
                else:
                    print("회원 정보를 삭제하는데 실패했습니다.")
                    conn.rollback()
                    main()
        except pymysql.MySQLError as e:
            print(e)
    
if __name__ == "__main__":
    main()

 

 

3. 실습 코드 설명

실습 코드 설명은 주석문이 많아서 가돈성이 떨어지지만 이해한 만큼 최대한 자세히 설명하려고 노력했다.

 

더보기

 

import pymysql                          # pymysql 모듈을 사용하기 위한 import
import re                               # re 모듈을 사용하기 위한 import

def print_double_line() :               # '='을 26번 출력하는 함수
    print(f'{'=' * 26}')
    
def print_single_line() :               # '-'을 26번 출력하는 함수
    print(f"{'-' * 26}")

def print_title(title) :                # 메뉴의 타이틀을 출력하는 함수, 매개변수로 title을 받음
    print()                             # 이전 작업과 분리하기 위한 개행
    print_double_line()
    print(title)                        # 받은 매개변수 출력
    print_single_line()

def ans_check(message, user_input) :    # 사용자의 answer를 체크하는 함수, 매개 변수로 message와 user_input을 받음
    while True:                         # while 무한 루프 
        i = input(message).upper()      # 받은 메시지는 출력하고, 사용자 입력을 받아 대문자로 변환 후 i에 저장
        if i in user_input :            # 사용자가 입력한 i에 user_input 튜플에 지정된 유효한 옵션 중 하나인지 확인
            return i                    # 옵션에 있는 입력 값이면 i를 반환
        else:                           # 그렇지 않으면 print를 출력 후 while문 다시 실행
            print("잘못된 입력입니다. 확인 후 다시 입력해 주세요.")

def print_main_menu():                  # 메인 메뉴를 출력하는 함수
    print_title('메뉴')                 # print_title() 함수에 매개변수로 '메뉴'를 넘김
    print('I : 회원 등록')
    print('S : 회원 검색')
    print('Q : 종료')
    print_double_line()

def main() :                            # 이 스크립트의 메인 함수
    print_main_menu()                   # 메인 메뉴 출력

    # menu 변수에 ans_check의 값을 저장 message를 주고 사용자의 입력은 "I", "S", "Q"로 제한하는 옵션을 붙임 
    menu = ans_check('메뉴를 입력하세요 : ', ("I", "S", "Q"))   
    if menu == 'I' :            # menu의 값이 I라면
        add_member()            # add_member() 함수 실행
    elif menu == 'S' :          # menu의 값이 S라면
        search_member()         # search_member() 함수 실행
    else :                      # 둘 다 아니면 종료 이때 elif를 사용해도 되지만 if 문의 연산을 한 번 더 하기 때문에
        print("종료합니다.")    # 효율적이지 못해 eles를 사용

def add_name_check(name):                   
    return bool(re.match('^[가-힣]+$', name))   
    # 사용자가 입력한 name의 문자열이 처음부터 끝까지 한국어 문자 범위와 하나 이상의 문자가 
    # 이 정규 표현식 패턴과 일치하는지 확인 후 True 또는 False 반환하는 함수
    # 이렇게 해야 특수문자 및 숫자도 검사 됨
    # "[가-힣]+", "^[가-힣]+"으로 했을 때 "가!"를 입력하면 범위 중 한 개 이상 매치 되므로 오류 없이 통과됨
    # "[가-힣]+$", 이렇게만 써도 특수문자 및 숫자도 검사되지만, ^을 써줌으로써 처음부터 끝까지라는 범위가 생김
   
def add_age_check(age) :           
    return bool(re.match(r'^([1-9]|[1-9][0-9]|1[0-4][0-9]|150)$', age))     
    # 사용자가 입력한 age의 문자열이 처음부터 끝까지 1에서 150까지 범위와 일치하는지
    # 확인 후 True 또는 False 반환하는 함수

   
def add_email_check(email) :        
    return bool(re.match(r'^[a-zA-Z0-9_-]+@[a-zA-Z0-9]+\.[a-zA-Z]{2,}$', email)) 
    # 사용자가 입력한 eamil의 문자열이 처음부터 끝까지 이 정규 표현식 패턴과 일치하는지
    # 확인 후 True 또는 False 반환하는 함수
    # [a-zA-Z0-9_-] a-z 영어 소문자, A-Z 영어 대문자, 숫자, 특수문자 "_", "-"를 포함 
    # 아이디 부분에 다른 특수문자도 포함하고 싶다면 특수문자 "-" 뒤에 추가 입력하면 됨 *(네이버 아이디 기준을 따름)
    # "@"는 아이디와 도메인 네임 중간에 필수 포함
    # [a-zA-Z0-9] a-z 영어 소문자, A-Z 영어 대문자, 숫자
    # "\." 이스케이프 문자로 .을 표현 도네임 네임과 최상위 도메인을 구분을 위해 필수 포함
    # [a-zA-Z]{2,} a-z 영어 소문자, A-Z 영어 대문자


def input_check(message, pattern_name) :   
    # add_member()에서 사용자 입력값을 검사하는 함수, 정규 표현식 체크 함수의 이름을 매개변수로 받음   

    while True :                      # while 무한 루프
        user_input = input(message)   # message를 보여주고 사용자 입력을 user_input에 저장
        if pattern_name(user_input) : # 받아온 정규 표현식 함수 이름을 넣고 사용자 입력을 매개변수로 넘김
            return user_input         # 각 정규 표현식 체크에서 True가 반환되면 if문이 실행 돼서 uesr_input을 반환
        else :                        # 정규 표현식 패턴 체크에서 False가 반환되면 else문 실행
            print("입력이 잘못되었습니다. 다시 입력하세요")    # 문자열 출력 후 while문 다시 실행


def add_member():               # 회원 등록 함수 
    print_title('회원 등록')    # print_title() 함수에 매개변수로 '회원 등록'을 넘김

    name = input_check("이름 : ", add_name_check) 
    # 사용자가 입력한 값을 add_name_check() 함수에서 True를 반환하면 name에 저장 
     
    age = input_check("나이 : ", add_age_check)
    # 사용자가 입력한 값을 add_age_check() 함수에서 True를 반환하면 age에 저장 

    email = input_check('이메일 : ', add_email_check)
    # 사용자가 입력한 값을 add_email_check() 함수에서 True를 반환하면 email에 저장 
    
    print_single_line()

    YN = ans_check('등록하시겠습니까? (Y : 등록 / N : 취소) :', ('Y', "N"))
    # 사용자가 입력한 값을 ans_check에서 확인 후 YN에 Y 또는 N 저장

    if YN == 'Y' :  # YN이 Y라면
        query = "INSERT INTO members (member_name, member_age, member_email) VALUES (%s, %s, %s)"
        # query에 SQL문을 저장 members 테이블에 각 컬럼들에 값을 매개변수로 받아 INSERT 함

        try:        # 오류를 처리하기 위한 try - except 구문
            with pymysql.connect(host="localhost", port=3306, user="springboot", passwd="qwert12345",
                                db="sampledb", cursorclass=pymysql.cursors.DictCursor) as conn:
                # with문으로 pymysql을 실행, with문으로 실행함으로써 with문를 벗어나는 순간 자동으로 close 함
                
                curr = conn.cursor()    # 커서를 생성해서 입력 쿼리를 실행
                count = curr.execute(query, (name, age, email))
                # 쿼리를 실행할 때 위 정규 표현식 체크가 끝난 변수들을 매개변수로 넘김 

                if count == 1:      # count가 1이면 if문 실행 SQL에 정상적으로 데이터 입력이 되면 실행됨
                    print("회원 정보를 정상적으로 등록했습니다.")
                    conn.commit()   # 현재 트랜잭션을 커밋, 변경 사항을 영구적으로 적용
                    yn = ans_check('추가 등록하시겠습니까? (Y : 등록 / N : 메인 메뉴) :', ('Y', "N"))
                    # 메인 메뉴로 바로 가지 않고 추가 등록을 물어보기 위한 사용자 입력 함수
                    # ans_check에서 입력 체크

                    if yn == 'Y' :      
                        add_member()    # add_member() 함수를 다시 불러 추가 등록함
                    else :              
                        main()          
                else:                   # count가 1이 아니면 else 실행
                    print("회원 정보를 등록하는데 실패했습니다.")
                    conn.rollback()     # 트랜잭션 커밋에 실패하면 변경 사항이 롤백되어 데이터베이스가 
                    main()              # 트랜잭션 시작 전 상태로 되돌아간 후 메인 메뉴로 이동
        except pymysql.MySQLError as e:     # 발생 오류와 오류 변수까지 포함한 except문
            print(e)                        # 오류 내용을 출력
    else :             
        YN =ans_check("회원 등록을 취소했습니다.\n다시 등록하시겠습니까? (Y : 등록 / N : 메인 메뉴) : ", ('Y', 'N'))
        # 회원 등록 추소 후 메인 메인 메뉴로 바로 가지 않고 다시 등록을 물어보기 위한 사용자 입력 함수
        # ans_check 입력 체크
        if YN == 'Y' :      
            add_member()    # add_member() 함수를 다시 불러 처음부터 다시 등록함
        else :              
            print("회원 등록을 취소합니다.")    
            main()                              # 메인 메뉴 이동


def search_member() :           # 회원 검색 함수
    print_title("회원 검색")    # print_title() 함수에 매개변수로 '회원 검색'을 넘김
    name = input_check("이름 : ", add_name_check)     # 사용자 입력 정규 표현식 체크
    print_double_line()

    YN = ans_check('검색하시겠습니까? (Y : 검색 / N : 취소) : ', ('Y', "N"))    # 검색을 위한 사용자 answer 체크
    if YN == 'Y' :     
        query = "SELECT * FROM members WHERE member_name like %s"
        # SELECT문으로 members 테이블 member_name의 모든 열 중 사용자 입력값을 포함한 행을 반환

        try:           
            with pymysql.connect(host="localhost", port=3306, user="springboot", passwd="qwert12345",
                                db="sampledb", cursorclass=pymysql.cursors.DictCursor, autocommit=True) as conn:
                               
                curr = conn.cursor()
                count = curr.execute(query, ('%'+name+'%',))
                results = curr.fetchall()   # 커서로부터 모든 행(레코드)을 반환
                print_title(f'회원 검색 결과 (총 {count}건)') # print_title() 함수에 매개변수로 문자열을 넘김

                if count == 0 :
                    print("일치하는 결과가 없습니다. 다시 검색해 주세요.")
                    search_member()             # 다시 검색을 위해 search_member() 함수 부름
                else :
                    id_nums = []                # id 번호를 저장하기 위한 리스트
                    for result in results :     # 검색한 모든 결과가 들어있는 results에서 하나씩 result에 넣음
                        id_nums.append(str(result['member_id']))    # id 번호를 id_nums에 str로 추가
                        print(f"{result['member_id']} : {result['member_name']}")   
                        # 검색한 결과를 ID : 이름으로 출력
                    print_single_line()
                    id_nums.append('N')     # id_num 리스트에는 id 번호만 있는데 N이 없을 경우          
                    detail_member(id_nums)  # detail_member()에서 N을 사용할 수 없어 
                                            # 잘못된 입력이라고 버그 남 그렇기 때문에 N을 추가  (!!중요!!)
                                            # id_nums에는 (예 : [1, 12, 24, N]) 마지막에 N이 같이 저장됨              
        except pymysql.MySQLError as e:     
            print(e)                        
    else :
        YN =ans_check("회원 검색을 취소했습니다.\n다시 검색하시겠습니까? (Y : 검색 / N : 메인 메뉴) : ", ('Y', 'N'))
        # 메인 메뉴로 바로가지 않고 다시 검색 질문
        if YN == 'Y' :
            search_member()     # 다시 검색을 원하면 search_member() 실행
        else :
            print("회원 검색을 취소합니다.")
            main()


def detail_member(id_nums) :    # 회원 상세 조회 함수
    id_num = ans_check("회원 상세 조회 하시겠습니까? (번호 : 상세 조회 / N : 메인 메뉴) : ", id_nums)
    if id_num == 'N' :
        print('상세 조회를 취소합니다.')
        main()
    else :
        print_title('회원 상세 조회')
        query = "SELECT * FROM members WHERE member_id = %s"
        # 여기서 정확한 한 명의 회원 상세 조회이기 때문에 like 아니고 = 으로 함 
        try:
            with pymysql.connect(host="localhost", port=3306, user="springboot", passwd="qwert12345",
                                db="sampledb", cursorclass=pymysql.cursors.DictCursor, autocommit=True) as conn:
                
                curr = conn.cursor()
                curr.execute(query, (id_num,))
                member = curr.fetchone()    # 커서로부터 하나의 행(레코드)을 반환, 한 사람 것만 가져오면 됨

                print(f"ID : {member['member_id']}")
                print(f"이름 : {member['member_name']}")
                print(f"나이 : {member['member_age']}")
                print(f"이메일 : {member['member_email']}")
                    
                print_double_line()
                
                UDN = ans_check('어떤 작업을 하시겠습니까? (U : 수정 / D : 삭제 / N : 메인 메뉴) : ', 
                                ('U', 'D','N'))     # 다음 작업을 위한 사용자 answer 체크
                if UDN == 'U' :
                    update_member(member['member_id'])  # 회원 수정 함수로 이동
                elif UDN == 'D' :
                    delete_member(member['member_id'])  # 회원 삭제 함수로 이동
                else :
                    main()
                
        except pymysql.MySQLError as e:
            print(e)


def update_member(id) :         # 회원 수정 함수
    print_title('회원 수정')    # print_title() 함수
    query = "SELECT * FROM members WHERE member_id = %s"
    # 위 상세 조회와 같이 하나만 가져오면 되기 때문에 "="
    try:
        with pymysql.connect(host="localhost", port=3306, user="springboot", passwd="qwert12345",
                            db="sampledb", cursorclass=pymysql.cursors.DictCursor) as conn:
            
            curr = conn.cursor()
            curr.execute(query, (id,))
            member = curr.fetchone()    # 커서로부터 하나의 행(레코드)을 반환, 한 사람 것만 가져오면 됨

            print(f"ID : {member['member_id']}")
            print(f"이름 : {member['member_name']}")
            print(f"나이 : {member['member_age']}")
            print(f"이메일 : {member['member_email']}")
            print_double_line()

            age = input_check("나이 : ", add_age_check)
            email = input_check('이메일 : ', add_email_check)
            YN = ans_check("수정할까요? (Y : 수정 / N : 취소) : ", ("Y", "N"))
        
            if YN == 'N' :
                YSN = ans_check(f"{member['member_name']} 수정을 취소했습니다.\n"
                               f"{member['member_name']} 다시 수정하시려면 Y, 다른 검색 하시려면 S를 입력하세요."
                               " (Y : 수정 / S : 검색 / N : 메인 메뉴) : ",
                               ("Y", 'S', "N"))
                # 방금 수정 중인 사람의 수정을 다시 하기 또는 다른 사람 검색을 위한 변수
                if YSN == "Y" :
                    update_member(id)   
                    # 매개변수를 id로 받기 때문에 방금 수정 작업하던 데이터만 수정 가능 
                elif YSN == 'S' :
                    print("수정 취소 합니다.")
                    search_member()     
                    # 위의 문제로 다른 데이터를 수정하기 위해서는 처음부터 다시 검색해야 함
                else :
                    print("수정 취소 합니다.")
                    main()
            else :
                query = "UPDATE members SET member_age = %s, member_email = %s WHERE member_id = %s"
                # members 테이블에 사용자가 입력한 member_id에서 
                # member_age와 member_email을 사용자 입력 값으로 변경 

                count = curr.execute(query, (age, email, id)) 
                # 쿼리 실행 시 사용자 입력 값을 매개변수로 넘김

                if count == 1 :
                    print("회원 정보를 정상적으로 수정했습니다.")
                    conn.commit()
                    main()
                else:
                    print("회원 정보를 등록하는데 실패했습니다.")
                    conn.rollback()
                    main()
    except pymysql.MySQLError as e:
            print(e)


def delete_member(id) :     #회원 정보 삭제 함수, 매개변수 id 받음
    YN = ans_check("회원 정보를 삭제하시겠습니까? (Y : 삭제 / N : 취소) : ", ('Y', 'N'))
    if YN== 'N' :
        print("회원 정보 삭제를 취소했습니다.")
        main()
    else :
        query = 'DELETE FROM members WHERE member_id = %s'
        # members 테이블에 사용자가 입력한 member_id를 삭제
        try:
            with pymysql.connect(host="localhost", port=3306, user="springboot", passwd="qwert12345",
                            db="sampledb", cursorclass=pymysql.cursors.DictCursor) as conn:
            
                curr = conn.cursor()
                count = curr.execute(query, (id,))

                if count == 1 :
                    print("회원 정보를 정상적으로 삭제했습니다.")
                    conn.commit()
                    main()
                else:
                    print("회원 정보를 삭제하는데 실패했습니다.")
                    conn.rollback()
                    main()
        except pymysql.MySQLError as e:
            print(e)
    
if __name__ == "__main__":  
    # 직접 이 파일을 실행했을 때 True가 돼 if문 실행 
    # 인터프리터나 다른 파일에서 이 모듈을 불러 사용할 때는 False가 돼 if문 실행 안 함
    main()

 

댓글