포시코딩

[Flask + MySQL] CRUD using Pycharm 본문

Python/Flask

[Flask + MySQL] CRUD using Pycharm

포시 2022. 12. 1. 12:23
728x90

개요

Flask 상에서 MySQL과 연동해 CRUD 하는 법 정리

 

준비

먼저 API 서버를 준비하자

1. 프로젝트 세팅

따라만 하세요 따라만 하세요!
가운데 + 버튼 클릭
flask를 검색해서 왼쪽 하단 install
pymysql도 미리 설치

2. Flask 서버 세팅

from flask import Flask, jsonify
app = Flask(__name__)

@app.route('/')
def home():
    print('hi')
    return jsonify({'result': 'done'})

if __name__ == '__main__':
    app.run('0.0.0.0', port=5000, debug=True)

3. 서버 실행 및 확인

app.py 코드 위에서 오른쪽 클릭 -> Run 'app' 

이렇게 뜨면 서버가 잘 실행된거다.

화면에 뜬 파란글씨 중 하나로 컨트롤 + 클릭을 통해 들어가거나

localhost:5000에 접속하면 

'/'로 접속할 때 리턴시켰던 json데이터가 잘 출력되는걸 볼 수 있다. 

 

MySQL 연동

1. pymysql을 통해 db 연동

import pymysql
db = pymysql.connect(
    host="localhost", 	# 데이터베이스 주소
    user="root", 	# 유저네임
    passwd="password", 	# 패스워드
    db="dbname", 	# 사용할 DB
    charset="utf8"	# 인코딩
)

db 연결을 끝냈으니 아까 만들었던 home() 함수에 

데이터를 넣어놓은 테이블을 불러와보자

 

2. READ

SELECT 코드

일단 먼저 DB에 데이터를 넣어놨으니 SELECT문을 통해 연동도 확인할겸 잘 가져와지나 테스트해보자

@app.route('/')
def home():

  # DB 연결
  db = pymysql.connect(
      host="localhost", 	# 데이터베이스 주소
      user="root", 		# 유저네임
      passwd="password", 	# 패스워드
      db="dbname", 		# 사용할 DB
      charset="utf8"		# 인코딩
  )
  
  # 쿼리문
  sql = 'SELECT * from student'
  
  # 쿼리 실행
  cursor = db.cursor()  # default 튜플 타입으로 받기
  # cursor = db.cursor(pymysql.cursors.DictCursor)  # Dictionary 타입으로 받기
  cursor.execute(sql)
  
  # 결과 받고 컨트롤하기
  data = cursor.fetchall()
  print(data)	# ((1, '조성훈', '010-1111-2222'),) 출력
  
  # DB 연결 종료
  db.commit()
  db.close()

  return jsonify({'result': 'done'})

제대로 동작하는 것을 볼 수 있다.

 

3. CREATE

INSERT 기능에 들어가기 앞서 

내 서버에 요청값이 제대로 전달되나 먼저 테스트 해보았다. 

 

postman 프로그램을 썼고 평소처럼 request.form['name'] 이런식으로 받아봤다.

@app.route('/student', methods=["POST"])
def insert():
    input_name = request.form['input_name']
    input_phone = request.form['input_phone']
    print(input_name, input_phone)
    
    return jsonify({'result': 'done'})

{'result': 'done'}이 와야하는 결과값에 이상한 HTML이 있는걸로 봐선 뭔가 잘못됐다.
난리난 파이참 콘솔창

위처럼 POST 요청을 보냈는데 콘솔이 시뻘건 글로 도배되면서 서버가 꺼졌다..

보면 요청 자체를 못받고 있는데 두가지 해결법을 찾아냈다.

 

요청값 받는 방법 1. Body -> form-data로 보내기

애초에 Params 탭이 맨 앞에 있다고 해서 쓰면 안되고

이 방법이 기존 Axios를 통해 body에 보냈던 그 역할을 대신 해주나보다. 

이렇게 Body탭에서 form-data로 설정해준 뒤 값을 보내면 서버에서도 정상적으로 받고

결과값도 제대로 리턴 받는다. 

물론 위에 적은 서버 코드 그대로 실행하면 된다. 

 

요청값 받는 방법 2. Body -> raw에서 json 데이터로 보내기

마찬가지로 Body 탭에서 form-data를 raw로 바꾸고 옆에 Text를 JSON으로 바꾼다. 

위 사진처럼 보낼 데이터를 JSON 형식으로 작성한 뒤 보내면 되는데 서버쪽 코드를 아래와 같이 수정해줘야 한다. 

@app.route('/student', methods=["POST"])
def insert():
    req = request.get_json()
    print(req)
    
    return jsonify({'result': 'done'})

잘 받아와진다.

하지만 나는 1번 방법을 쓸거임

 

INSERT 코드

@app.route('/student', methods=["POST"])
def insert():
  name = request.form['name']
  phone = request.form['phone']

  # DB 연결
  db = pymysql.connect(
      host="localhost", 	# 데이터베이스 주소
      user="root", 		# 유저네임
      passwd="password", 	# 패스워드
      db="dbname", 		# 사용할 DB
      charset="utf8"		# 인코딩
  )
  
  # 쿼리문
  sql = 'INSERT INTO student (name, phone) VALUES (%s, %s)'
  
  # 쿼리 실행
  cursor = db.cursor()
  cursor.execute(sql, (name, phone))
  
  # DB 종료
  db.commit()
  db.close()
  
  return jsonify({'result': 'done'})

POSTMAN 에서 요청
DBeaver를 통해 확인

제대로 INSERT 된 것을 확인할 수 있다.

 

4. UPDATE, DELETE

코드는 INSERT 와 동일하니 HTTP method만 바꿔주는 방식으로 구현해주면 된다.

 

UPDATE 코드

@app.route('/student', methods=["PATCH"])
def update():
  name = request.form['name']
  phone = request.form['phone']
    
  db = pymysql.connect(
      host="localhost", 	# 데이터베이스 주소
      user="root", 		# 유저네임
      passwd="password", 	# 패스워드
      db="dbname", 		# 사용할 DB
      charset="utf8"		# 인코딩
  )
  sql = 'UPDATE student SET phone = %s WHERE name = %s'
  cursor = db.cursor()
  cursor.execute(sql, (phone, name)) # 순서 주의
  db.commit()
  db.close()
  return jsonify({'result': 'done'})

DELETE 코드

@app.route('/student', methods=["DELETE"])
def delete():
  name = request.form['name']
    
  db = pymysql.connect(
      host="localhost", 	# 데이터베이스 주소
      user="root", 		# 유저네임
      passwd="password", 	# 패스워드
      db="dbname", 		# 사용할 DB
      charset="utf8"		# 인코딩
  )
  sql = 'DELETE FROM student WHERE name = %s'
  cursor = db.cursor()
  cursor.execute(sql, (name))
  db.commit()
  db.close()
  return jsonify({'result': 'done'})

 

728x90