파트 13-2. 파이썬과 mysql 연동

1. pymysql 라이브러리 설치


그림1 파이썬 자체에는 mysql을 인식하는 기능이 없으므로 외부 라이브러리인 pymysql을 먼저 설치해야 한다. 명령 프롬프트에서 파이썬이 설치된 위치로 이동한 후에 pip install pymysql 로 설치하자.

2. mysql에 데이터 입력을 위한 피이썬 코딩 순서


그림2

위와 같은 데이터베이스를 구축하는 연습을 하자. 먼저 workbench에서 hanbitdb 데이터베이스만 만들어놓고 workbench를 종료시키자.
파이썬에서 데이터를 입력하기 위해서는 다음과 같은 단계를 거친다. 그림3

  • 데이터베이스 연결 : pymysql을 임포트한 후에, pymysql.connect(host=서버,user=사용자,password=암호,db=데이터베이스,charset=문자세트)문으로 데이터베이스와 연결해야 한다.
  • 커서 생성 : 커서는 데이터베이스에 sql문을 실행하거나, 실행된 결과를 돌려받는 통로로 생각하면 된다.
  • 테이블 만들기 : 커서이름.execute() 함수의 매개변수로 sql문을 넘겨주면 된다.
  • 데이터 입력 : 커서이름.execute 함수의 매개변수로 sql문을 넘겨주면 된다.
  • 입력한 데이터 저장 : 지금까지 입력한 내용은 데이터베이스에 완전히 저장된 것은 아니며, 임시로 저장된 상태이다. 이를 확실히 저장하는 것이 커밋이다.
  • 데이터베이스 닫기 : 사용을 끝냈다면 연결된 데이터베이스를 닫아야 한다.
import pymysql # 파이썬과 mysql 연결을 위한 import

# 전역변수 선언부
conn, cur = None, None
data1, data2, data3, data4 = "", "", "", ""
sql=""

# 메인 코드
# mysql과 연결 host,user,password,사용할db,한글이 깨지지않도록utf8
conn = pymysql.connect(host='127.0.0.1', user='root', password='1234', db='hanbitDB', charset='utf8')
cur = conn.cursor() # 커서 생성

# 대부분 아래 두줄은 안쓴다 db에 이미 테이블이 만들어져있는 경우가 대부분
sql = "create table if not exists usertable(id char(4),username char(15), email char(20), birthyear int)"
cur.execute(sql) # 실행

while (True) :
    data1 = input("사용자 ID ==> ")
    if data1 == "" :
        break;
    data2 = input("사용자 이름 ==> ")
    data3 = input("사용자 이메일 ==> ")
    data4 = input("사용자 출생연도 ==> ")
    # 입력받은 정보로 insert문 작성 
    sql = "INSERT INTO userTable VALUES('" + data1 + "','" + data2 + "','" + data3 + "'," + data4 + ")"
    cur.execute(sql) # 실행

conn.commit() # 입력한 데이터 저장
conn.close() # 연결자 닫기


3. mysql의 데이터 조회를 위한 파이썬 코딩 순서


파이썬에서 데이터를 조회하기 위해서는 다음과 같은 단계를 거친다.

그림4

import pymysql

# 전역변수 선언부
con, cur = None, None
data1, data2, data3, data4 = "", "", "", ""
row=None

# 메인 코드
conn = pymysql.connect(host='127.0.0.1', user='root', password='1234', db='hanbitDB', charset='utf8')
cur = conn.cursor()

# 조회결과가 cur에 들어간다.
cur.execute("SELECT * FROM userTable")

print("사용자ID    사용자이름    이메일        출생연도")
print("----------------------------------------------------")

while (True) :
    # fetchone()으로 한 행씩 가져오기
    row = cur.fetchone()
    if row== None :
        break
    data1,data2,data3,data4 = row
    print("%5s   %15s   %15s   %d" % (data1, data2, data3, data4))

conn.close()


4. gui를 활용한 데이터 입력/조회 프로그램


그림5

위와 같이 데이터의 입력 수정이 가능하고, 초기화 버튼을 클릭하면 테이블이 삭제되고 다시 생성되도록 하자.

import pymysql
from tkinter import *
from tkinter import messagebox


## 함수 선언부
def insertData() :
    con, cur = None, None
    data1, data2, data3, data4 = "", "", "", ""
    sql=""

    conn = pymysql.connect(host='127.0.0.1', user='root', password='1234', db='hanbitDB', charset='utf8')
    cur = conn.cursor()

    # 입력창에서 get로 가져와서 변수에 저장
    data1 = edt1.get();    data2 = edt2.get();    data3 = edt3.get();    data4 = edt4.get()
    # 입력 받은 데이터로 insert문 작성
    try :
        sql = "INSERT INTO userTable VALUES('" + data1 + "','" + data2 + "','" + data3 + "'," + data4 + ")"
        cur.execute(sql)
    except :
        messagebox.showerror('오류', '데이터 입력 오류가 발생함')
    else :
        messagebox.showinfo('성공', '데이터 입력 성공')
    conn.commit()
    conn.close()

def selectData() :
    strData1, strData2, strData3, strData4  = [], [], [], []
    conn = pymysql.connect(host='127.0.0.1', user='root', password='1234', db='hanbitDB', charset='utf8')
    cur = conn.cursor()
    cur.execute("SELECT * FROM userTable") # 조회 데이터 가져오기
    # 맨 위에 줄의 내용을 구분하기 위해서 append
    strData1.append("사용자ID");      strData2.append("사용자이름")
    strData3.append("이메일");         strData4.append("출생연도")
    strData1.append("-----------");    strData2.append("-----------")
    strData3.append("-----------");    strData4.append("-----------")

    # 데이터 가져와서 리스트에 append
    while (True) :
        row = cur.fetchone()
        if row== None :
            break;
        strData1.append(row[0]);        strData2.append(row[1])
        strData3.append(row[2]);        strData4.append(row[3])

    # 조회하기 전에 먼저 노란박스 4부분에 나와있던 데이터를 지운다
    listData1.delete(0,listData1.size() - 1);    listData2.delete(0,listData2.size() - 1)
    listData3.delete(0,listData3.size() - 1);    listData4.delete(0,listData4.size() - 1)
    # 다시 데이터를 넣는다. insert(위치, 요소)
    for item1, item2, item3, item4 in zip(strData1, strData2, strData3, strData4 ):
        listData1.insert(END, item1);        listData2.insert(END, item2)
        listData3.insert(END, item3);        listData4.insert(END, item4)
    conn.close()    

## 메인 코드부
window = Tk()
window.geometry("600x300")
window.title("GUI 데이터 입력")

# 화면 분할과 출력
edtFrame = Frame(window);
edtFrame.pack()
listFrame = Frame(window)
listFrame.pack(side = BOTTOM,fill=BOTH, expand=1)

# 위쪽 입력창 만들기
edt1= Entry(edtFrame, width=10);    edt1.pack(side=LEFT,padx=10,pady=10)
edt2= Entry(edtFrame, width=10);    edt2.pack(side=LEFT,padx=10,pady=10)
edt3= Entry(edtFrame, width=10);    edt3.pack(side=LEFT,padx=10,pady=10)
edt4= Entry(edtFrame, width=10);    edt4.pack(side=LEFT,padx=10,pady=10)

# 버튼 만들기
btnInsert = Button(edtFrame, text="입력", command = insertData)
btnInsert.pack(side=LEFT,padx=10,pady=10)
btnSelect = Button(edtFrame, text="조회", command =selectData )
btnSelect.pack(side=LEFT,padx=10,pady=10)

# 리스트박스만들기
listData1 = Listbox(listFrame,bg = 'yellow');
listData1.pack(side=LEFT,fill=BOTH, expand=1)
listData2 = Listbox(listFrame,bg = 'yellow')
listData2.pack(side=LEFT,fill=BOTH, expand=1)
listData3 = Listbox(listFrame,bg = 'yellow')
listData3.pack(side=LEFT,fill=BOTH, expand=1)
listData4 = Listbox(listFrame,bg = 'yellow')
listData4.pack(side=LEFT,fill=BOTH, expand=1)

window.mainloop()
  • expand옵션은 요구되지 않은 공간을 모두 요구하고자 할 경우 사용하는 옵션이다. 즉, 현재 틀에서 요구할 수 있는 모든 공간을 요구하게끔 하는 옵션이다.
  • fill은 현재 사용된 공간에서 사용되지 않은 공간으로까지 늘리고자 할 때 사용한다. x = 수평으로만 늘리기, y는 수직으로만 늘리기, both = 수평,수직 모두 늘리기, none = 늘리지 않기

© 2021. By Backtony