python, mysql, Flask 연동한 CRUD 예제

작성: 2021.03.24

수정: 2021.03.24

읽는시간: 00 분

Programming/Python

반응형

mysql 연동을 아직 못해봤으면 아래 글을 먼저 참고해주세요

shanepark.tistory.com/44?category=1191756

 

python 에서 pymysql 이용해 mysql과 연결하기, CRUD 예제

일단 MYSQL이 설치되어 있지 않다면 설치 및 초기 설정이 필요합니다. shanepark.tistory.com/41 mac) MYSQL 설치 및 초기설정하기 HOMEBREW 패키지 설치를 이용해 설치하는게 가장 간단합니다. [ homebrew가 설치

shanepark.tistory.com

Flask 를 안써봤다면 아래 글을 먼저 참고해주세요

shanepark.tistory.com/56?category=1191756

 

파이썬 Flask 사용법 - 1) Hello Flask

제가 사용중인 conda 에는 기본적으로 flask가 설치되어 있어 따로 설치 할 필요는 없었습니다. 파이썬 코드를 작성해봅니다. from flask import Flask app = Flask(__name__) @app.route('/') def index(): retu..

shanepark.tistory.com

 

 


 

MYSQL 서버 있는 자료에 대해 Flask 를 이용해 웹페이지에서 CRUD( Create, Read, Update, Delete)를 해보겠습니다.

일단 MYSQL에 emp 테이블을 먼저 만들어 줍니다. 사원번호, 이름, 부서, 전화번호의 간단한 구조를 가진 테이블입니다.

CREATE TABLE `emp` (
  `empno` varchar(50) NOT NULL,
  `name` varchar(50) DEFAULT NULL,
  `department` varchar(50) DEFAULT NULL,
  `phone` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`empno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

간단하게 자료도 몇개 넣어줬습니다.

 

Flask 를 쓰기 전에 먼저 pymysql 만을 활용해서 필요한 dao를 작성해줍니다.

main 함수에서 , 각각 작성한 쿼리들이 잘 작동하는지도 테스트 해봅니다. 

 

import pymysql

class MyEmpDao:
    def __init__(self):
        pass
    
    def getEmps(self):
        ret = []
        db = pymysql.connect(host='localhost', user='root', db='python', password='python', charset='utf8')
        curs = db.cursor()
        
        sql = "select * from emp";
        curs.execute(sql)
        
        rows = curs.fetchall()
        for e in rows:
            temp = {'empno':e[0],'name':e[1],'department':e[2],'phone':e[3] }
            ret.append(temp)
        
        db.commit()
        db.close()
        return ret
    
    def insEmp(self, empno, name, department,phone):
        db = pymysql.connect(host='localhost', user='root', db='python', password='python', charset='utf8')
        curs = db.cursor()
        
        sql = '''insert into emp (empno, name, department, phone) values(%s,%s,%s,%s)'''
        curs.execute(sql,(empno, name, department,phone))
        db.commit()
        db.close()
    
    def updEmp(self, empno, name, department,phone): 
        db = pymysql.connect(host='localhost', user='root', db='python', password='python', charset='utf8')
        curs = db.cursor()
        
        sql = "update emp set name=%s, department=%s, phone=%s where empno=%s"
        curs.execute(sql,(name, department, phone, empno))
        db.commit()
        db.close()
    def delEmp(self, empno):
        db = pymysql.connect(host='localhost', user='root', db='python', password='python', charset='utf8')
        curs = db.cursor()
        
        sql = "delete from emp where empno=%s"
        curs.execute(sql,empno)
        db.commit()
        db.close()

if __name__ == '__main__':
    #MyEmpDao().insEmp('aaa', 'bb', 'cc', 'dd')
    #MyEmpDao().updEmp('aa', 'dd', 'dd', 'aa')
    #MyEmpDao().delEmp('aaa')
    emplist = MyEmpDao().getEmps();
    print(emplist)

클릭 하면 크게 보입니다.

추가, 편집, 삭제는 주석을 걸어뒀으니 테스트 할때 주석을 풀어서 하면 됩니다.

문제없이 emplist를 잘 받아오는 것을 확인 했습니다.

 

같은 패키지에 flask를 사용할 모듈을 하나 만들어줍니다. myflask01.py 로 만들었습니다.

from flask import Flask
from flask.templating import render_template

from day12.mydao import MyEmpDao

app = Flask(__name__)

@app.route('/emp01')
def emp():
    empList = MyEmpDao().getEmps();
    return render_template("emp01.html", empList=empList)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

 

templates 폴더에 emp01.html 파일도 만듭니다.

<!DOCTYPE html>
<html>
<head>
<style>
table, th, td{
	border : 1px solid black;
}
</style>
<meta charset="UTF-8">
<title>회원관리</title>
</head>
<body>
<table>
	<tr>
		<th>사번</th>
		<th>이름</th>
		<th>부서</th>
		<th>전화번호</th>
	</tr>
		{% for emp in empList%}
		<tr>
			<td>{{emp.empno}}</td>
			<td>{{emp.name}}</td>
			<td>{{emp.department}}</td>
			<td>{{emp.phone}}</td>
		</tr>
		{% endfor %}
</table>
</body>
</html>

 

패키지 구조는 다음과 같습니다.

myflask01.py 파일을 실행 한 뒤에 웹브라우저에 http://0.0.0.0/emp01 를 치고 접속하면 DB에서 받아온 정보들이 테이블에 잘 들어와있는 것을 확인 할 수 있습니다.

 


 

이번에는  Create, Update, Delete 기능을 사용해보겠습니다. 

비동기 요청을 위한 ajax 사용을 위해 jquery 가 필요한데요, static 폴더 구조를 활용 할 수 있습니다.

 

패키지 구조는 다음과 같습니다. 한 패키지 안에 static 폴더, templates 폴더가 있고 , 같은 경로에 모듈들이 들어있습니다.

emp02.html 파일입니다.

<!DOCTYPE html>
<html>
<head>
<script src="/js/jquery-3.6.0.js"></script>
<style>
table, th, td{
	border : 1px solid black;
	text-align : center;
}
.btn{
	font-size : 1.2em;
}
</style>
<meta charset="UTF-8">
<title>회원관리</title>
</head>
<body>
<table>
	<tr>
		<th>사번</th>
		<th>이름</th>
		<th>부서</th>
		<th>전화번호</th>
	</tr>
		{% for emp in empList%}
		<tr>
			<td>
				<a href="javascript:fn_detail(
				'{{emp.empno}}','{{emp.name}}','{{emp.department}}','{{emp.phone}}'
				)">{{emp.empno}}</a>
			</td>
			<td>{{emp.name}}</td>
			<td>{{emp.department}}</td>
			<td>{{emp.phone}}</td>
		</tr>
		{% endfor %}
</table><br/>
<table>
	<tr>
		<th>사번</th>
		<td>
			<input type="text" id="empno">
		</td>
	</tr>
	<tr>
		<th>이름</th>
		<td>
			<input type="text" id="name">
		</td>
	</tr>
	<tr>
		<th>부서</th>
		<td>
			<input type="text" id="department">
		</td>
	</tr>
	<tr>
		<th>전화번호</th>
		<td>
			<input type="text" id="phone">
		</td>
	</tr>
	<tr>
		<td colspan="2">
			<input onclick="fun_add()" id="add" class="btn" type="button" value="추가">
			<input onclick="fun_mod()"id="mod" class="btn" type="button" value="수정">
			<input onclick="fun_del()"id="del" class="btn" type="button" value="삭제">
		</td>
	</tr>
</table>
<script>
	function fun_add(){
		const empno = document.getElementById("empno").value
		const name = document.getElementById("name").value
		const department = document.getElementById("department").value
		const phone = document.getElementById("phone").value
		var param = {
			'empno' : empno,
			'name' : name,
			'department' : department,
			'phone' : phone
		}
		
		$.ajax({
			type : 'POST',
			url : '/ins.ajax',
			data : JSON.stringify(param),
			dataType : 'JSON',
			contentType : "application/json",
			success : function(data){
				location.reload()
			},
			error : function(request, status, error){
				
			}
		})
		
	}
	function fun_mod(){
		const empno = document.getElementById("empno").value
		const name = document.getElementById("name").value
		const department = document.getElementById("department").value
		const phone = document.getElementById("phone").value
		var param = {
			'empno' : empno,
			'name' : name,
			'department' : department,
			'phone' : phone
		}
		
		$.ajax({
			type : 'POST',
			url : '/mod.ajax',
			data : JSON.stringify(param),
			dataType : 'JSON',
			contentType : "application/json",
			success : function(data){
				location.reload()
			},
			error : function(request, status, error){
				
			}
		})
	}
	function fun_del(){
		const empno = document.getElementById("empno").value
		const name = document.getElementById("name").value
		const department = document.getElementById("department").value
		const phone = document.getElementById("phone").value
		var param = {
			'empno' : empno,
			'name' : name,
			'department' : department,
			'phone' : phone
		}
		
		$.ajax({
			type : 'POST',
			url : '/del.ajax',
			data : JSON.stringify(param),
			dataType : 'JSON',
			contentType : "application/json",
			success : function(data){
				location.reload()
			},
			error : function(request, status, error){
				
			}
		})
	}
	function fn_detail(empno, name, department, phone){
		var obj_empno = document.getElementById("empno");
		var obj_name = document.getElementById("name");
		var obj_department = document.getElementById("department");
		var obj_phone = document.getElementById("phone");
		
		obj_empno.value=empno;
		obj_name.value=name;
		obj_department.value=department;
		obj_phone.value=phone;
	}
</script>
</body>
</html>

 

 

그리고 파이썬 모듈입니다.

'''
Created on 24 Mar 2021
사원 추가/수정/삭제 기능 추가
@author: shane
'''
from flask import Flask, request
from flask.json import jsonify
from flask.templating import render_template

from day12.mydao import MyEmpDao


app = Flask(__name__, static_url_path="", static_folder='static')

@app.route('/')
@app.route('/emp02')
def emp():
    empList = MyEmpDao().getEmps();
    return render_template("emp02.html", empList=empList)

@app.route('/ins.ajax', methods=['POST'])
def ins_ajax():
    data = request.get_json()
    empno = data['empno']
    name = data['name']
    department = data['department']
    phone = data['phone']
    cnt = MyEmpDao().insEmp(empno, name, department, phone)
    result = "success" if cnt==1 else "fail"
    return jsonify(result = result)

@app.route('/mod.ajax', methods=['POST'])
def mod_ajax():
    data = request.get_json()
    empno = data['empno']
    name = data['name']
    department = data['department']
    phone = data['phone']
    cnt = MyEmpDao().updEmp(empno, name, department, phone)
    result = "success" if cnt==1 else "fail"
    return jsonify(result = result)

@app.route('/del.ajax', methods=['POST'])
def del_ajax():
    data = request.get_json()
    empno = data['empno']
    cnt = MyEmpDao().delEmp(empno)
    result = "success" if cnt==1 else "fail"
    return jsonify(result = result)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

 

main 함수보다 @app.route 가 더 아래 있으면 해당 함수로 도달하지를 못합니다. POST 메서드 들어간 route 를 맨 아래에 두었다가, method not allowed 405 오류가 계속 나서 제법 애를 먹었습니다. 위치에도 신경써주세요.

서버를 켠 뒤에 http://0.0.0.0/emp02 에 접속해서 확인해보면,

정상적으로 잘 불러옵니다. 사번을 누르면 해당 사번의 정보가 바로 아래 폼에 입력됩니다.

 

추가도 해보았습니다.

정상적으로 잘 추가됩니다.

수정도 잘 이루어집니다.

 

 

 

 

삭제도 문제 없습니다. 이상입니다.

반응형