본문 바로가기
Python/프로젝트03(도서관리)

프로젝트03. 도서 관리 프로그램 만들기4-sqlite3

by To올라운더 2023. 12. 4.
반응형

 

이제 회원을 등록해볼 차례이다.

 

1. 회원 테이블 구상하기

회원 등록시 필요한 정보는

 - 회원번호(내부 생성), 회원 ID, 회원 이름, 생년월인, 회원 상태, 연락처, 주소, 이메일, 현재 대여 권수, 메모1, 메모2

로 생성할 예정이다.

 

회원 상태는 승인대기, 장기간 미사용 고객이나 블랙리스트 고객의 상태를 표기 및 관리하기 위해 임의로 만든 컬럼이며,

 

현재 대여 권수 컬럼은 1명의 회원이 무제한으로 책을 대여하지 못하도록

1인이 최대 5권만 대여 가능하도록 조건을 주기 위해 설정한 컬럼이다.

 

메모1, 2는 혹시나 하는 마음에서 만들어 두는 예비용 컬럼이다.

프로그램을 만들 때 결과물을 정확히 예측하고 기획된 대로 만드는 것도 중요하지만

이런 예비용 컬럼을 한, 두개 정도 만들어 두면 혹시 빠트리거나 예상치 못한 상황에 대처하기가 유용하다.

 

- 컬럼명 및 설명

 members_no : 회원번호

 members_id : ID 

 members_name : 이름

 members_dob : 생년월일

 members_stat : 상태

 phone_no : 연락처

 address : 주소

 e_mail : 이메일

 rent_count : 현재 대여 권수

 memo1 : 메모1

 memo2 : 메모2

반응형

 

 

2. 테이블 생성 코드

# main_db.py
# 회원 테이블
cursor.execute('CREATE TABLE IF NOT EXISTS members(members_no integer primary key autoincrement , members_id text unique, members_name text, members_dob timestamp,\
    members_stat text, phone_no text, address text, e_mail text, rent_count integer, memo1 text, memo2 text)')

 

 

3. 등록 매서드 추가



# 회원 등록
def registe_members(members_id, members_name, members_dob, phone_no, address, e_mail):

    # ID 등록 여부 확인
    cursor.execute(f'select * from members where members_id = \'{members_id}\'')
    members_id_result = cursor.fetchall()

    # 같은 ID로 등록된 내역이 없으면
    if len(members_id_result) == 0: 

        cursor.execute("insert into members(members_id, members_name, members_dob, members_stat, phone_no, address, e_mail, rent_count, memo1, memo2) \
            values('{}','{}','{}','{}','{}','{}','{}','{}','{}','{}')".format(members_id, members_name, members_dob, '대기', phone_no, address, e_mail, '0', '', ''))

        # registe_members('allrounder', '올라운더', '20020101', '010-1234-5678', '서울시 어딘가', 'to_allrounder@gmail.com')

    # 같은 ID로 등록된 내역이 있으면
    else :
        print('이미 등록된 ID 입니다.')



# 전체 등록 회원 확인
def select_members_all_view():
    cursor.execute('select * from members order by 1')
    view_list = cursor.fetchall()
    print(view_list)

 

해당 코드를 실행 해보면 [4. members Table 내역 전체 조회]와 [5. 회원 추가 테스트]를 확인할 수 있다.

등록 테스트를 진행해보면, 등록된 ID가 없을 때에는 등록을 진행하고,

등록된 ID가 있으면 skip 한다.

최초 등록 시에 계정의 상태 값이 '대기' 상태 이므로 관리자가 해당 상태를 변경해주면

사용 가능한 형태가 된다.

계정의 상태는 

대기 신규 회원 가입 후, 관리자 미확인 상태(대여 불가)
승인 신규 회원 가입 후, 관리자 확인 상태(대여 가능)
거절 신규 회원 가입 후, 관리자 확인 상태(대여 불가)
  - 1인 2계정 신청 또는 작성 내용 부족
지연반납 대여 후, 반납일 미준수자로 해당 상태에서 대여 불가
블랙 도서 파손 및 도서관 사용 거절 대상자(대여 불가)

 

로 계정의 상태를 확인하며, '승인' 상태일 때만 대여가 가능하도록 작성할 예정이다.

해당 상태 변경은 관리자 계정에서 진행할 수 있도록 기능을 추가한다.

 

아래와 같이 같은 ID가 등록되어 있지 않을 때에는 정상 등록이 진행되고,

 

같은 ID로 재등록 시도 시, 아래와 이미 등록된 ID로 등록되지 않는다.

 

 

4. 전체코드

import sqlite3


# DB생성 및 Auto Commit, RollBack
conn = sqlite3.connect(r'.\books_manager_database.db', isolation_level=None) # 해당 경로에 book_manager_database.db DB파일이 생성된다.

# 커서(Cursor)의 이용
cursor = conn.cursor()




######################################################################
# 테이블 생성(Data Type : TEXT, NUMERIC INTEGER, REAL, BLOB)



# 도서 기준 기본 테이블
cursor.execute('CREATE TABLE IF NOT EXISTS books_info(book_key integer primary key autoincrement , group_code integer, book_title text,\
    writer text, publisher text, total_count integer, available_count integer, lacation text )')


# 도서 기준 세부 테이블(도서 개별)
cursor.execute('CREATE TABLE IF NOT EXISTS book_detail_info(book_detail_key integer primary key autoincrement , books_key integer, user_key integer, rent_stat text,\
    rent_start_date timestamp, rent_expire_date timestamp)')


# 회원 테이블
cursor.execute('CREATE TABLE IF NOT EXISTS members(members_no integer primary key autoincrement , members_id text unique, members_name text, members_dob timestamp,\
    members_stat text, phone_no text, address text, e_mail text, rent_count integer, memo1 text, memo2 text)')


#########################################################################

# 동일 도서 등록 여부 확인
def check_books_info_by_title_publisher(book_title, publisher):

    cursor.execute(f'SELECT BOOK_KEY, TOTAL_COUNT, AVAILABLE_COUNT FROM BOOKS_INFO WHERE BOOK_TITLE = \'{book_title}\' AND PUBLISHER = \'{publisher}\'')
    select_check_book_result = cursor.fetchall()
    
    
    if len(select_check_book_result) == 0:
        check_book_result = (0, 0, 0)
    else:
        check_book_result = select_check_book_result[0]
    #print(check_book_result)

    return check_book_result

# cursor.execute(f'SELECT BOOK_KEY FROM BOOKS_INFO')

# 도서 등록 쿼리
def registe_new_book(group_code, book_title, writer, publisher, add_count, location):
    returned_check_book_result = check_books_info_by_title_publisher(book_title, publisher)

    # 동일 도서가 등록이 되어 있을 경우, returned_check_book_result 값이 books_info 테이블의 (book_key, total_count, available_cout) 값이 튜플로 반환됨
    # 미등록 되어 있을 경우, books_info 테이블에 해당 도서 등록 후, book_detail_info 등록
    if returned_check_book_result[0] == 0:
        cursor.execute("insert into books_info (group_code, book_title, writer, publisher, total_count, available_count, lacation) values('{}','{}','{}','{}','{}','{}','{}')".format(group_code, book_title, writer, publisher, add_count, add_count, location))

        # 신규 등록 시 book_key 값이 0인 상태로 book_detail_key 가 입력되어 check_books_info_by_title_publisher()를 재실행하여 신규로 입력된 book_key 값을 확인한다.
        returned_check_book_result = check_books_info_by_title_publisher(book_title, publisher)
        print('신규 등록 도서입니다.') 

    else:
        # books_info 수량 변경
        cursor.execute(f'UPDATE BOOKS_INFO SET TOTAL_COUNT = \'{int(returned_check_book_result[1])+ int(add_count)}\', AVAILABLE_COUNT = \'{int(returned_check_book_result[2])+ int(add_count)}\' \
            where book_key = \'{returned_check_book_result[0]}\'')
        print('사전에 등록된 추가 도서입니다.')
    
    # book_detail_info 등록
    for a_count in range(0, int(add_count)):
        cursor.execute("insert into book_detail_info (books_key, user_key, rent_stat, rent_start_date, rent_expire_date) values('{}','{}','{}','{}','{}')".format(returned_check_book_result[0], '', '', '', ''))


    # registe_new_book(100, '파이썬3', '후즈', 'C출판사', 3, '1F-3')

    # registe_new_book(100, '파이썬공부', 'To올라운더', 'A출판사', 4, '1F-A')

# 등록 도서 확인1(books_info)
def select_books_info_all_view():
    cursor.execute('select * from books_info order by 1')
    view_list = cursor.fetchall()
    print(view_list)


# 등록 도서 확인2(book_detail_info)
def select_book_detail_info_all_view():
    cursor.execute('select * from book_detail_info order by 1')
    view_list = cursor.fetchall()
    print(view_list)




# 회원 등록
def registe_members(members_id, members_name, members_dob, phone_no, address, e_mail):

    # ID 등록 여부 확인
    cursor.execute(f'select * from members where members_id = \'{members_id}\'')
    members_id_result = cursor.fetchall()

    # 같은 ID로 등록된 내역이 없으면
    if len(members_id_result) == 0: 

        cursor.execute("insert into members(members_id, members_name, members_dob, members_stat, phone_no, address, e_mail, rent_count, memo1, memo2) \
            values('{}','{}','{}','{}','{}','{}','{}','{}','{}','{}')".format(members_id, members_name, members_dob, '대기', phone_no, address, e_mail, '0', '', ''))

        # registe_members('allrounder', '올라운더', '20020101', '010-1234-5678', '서울시 어딘가', 'to_allrounder@gmail.com')

    # 같은 ID로 등록된 내역이 있으면
    else :
        print('이미 등록된 ID 입니다.')



# 전체 등록 회원 확인
def select_members_all_view():
    cursor.execute('select * from members order by 1')
    view_list = cursor.fetchall()
    print(view_list)



    

if __name__ == '__main__':
    while True:
        print('\n************************\n')
        print('사용할 동작을 입력하세요.')
        print('  1. books_info Table 내역 전체 조회')
        print('  2. book_detail_info Talbe 내역 전체 조회')
        print('  3. 도서 추가 테스트')
        print('  4. members Table 내역 전체 조회')
        print('  5. 회원 추가 테스트')
        print('  0. 프로그램 종료')

        choice_action = input('동작을 입력하세요. ex) 1 입력 후 엔터 : ')

        if choice_action == '1':
            select_books_info_all_view()

        elif choice_action == '2':
            select_book_detail_info_all_view()

        elif choice_action == '3':
            group_code = input('group_code 를 입력하세요 : ')
            book_title = input('도서의 제목을 입력하세요 : ')
            writer = input('저자를 입력하세요 : ')
            publisher = input('출판사를 입력하세요. : ')
            add_count = int(input('추가된 도서 권수를 숫자만 입력하세요. ex) 5 :'))
            location = input('도서의 위치를 입력하세요. : ')
            registe_new_book(group_code, book_title, writer, publisher, add_count, location)            
            #registe_new_book(100, '파이썬공부', 'To올라운더', 'A출판사', 4, '1F-A')

        elif choice_action == '4':
            select_members_all_view()

        elif choice_action == '5':
            members_id = input('회원 ID를 입력하세요 : ')
            members_name = input('이름을 입력하세요 : ')
            members_dob = input('생년월일을 입력하세요. 형식(YYYYMMDD) : ')
            # members_stat = '대기'
            phone_no = input('연락처를 입력하세요 : ')
            address = input('주소를 입력하세요 : ')
            e_mail = input('e-mail 주소를 입력하세요 : ')
            # rent_count = '0'
            # memo1 = ''
            # memo2 = ''

            registe_members(members_id, members_name, members_dob, phone_no, address, e_mail)
            #registe_members('allrounder', '올라운더', '20020101', '010-1234-5678', '서울시 어딘가', 'to_allrounder@gmail.com')

        elif choice_action == '0':
            print('\n\n프로그램을 종료합니다.')
            break

 

 

이제 다음 포스팅에서 대여 기능을 구현해보겠다.

반응형