API 개발/Restful API

Restful API : Python MySQL Connector 셀렉트 하는 방법

신강희 2024. 5. 24. 01:25
728x90

< Python MySQL Connector 셀렉트 하는 방법 >

 

1) 전체 레시피 가져오는 API를 만들어 보자 우선, 포스트맨을 실행시켜 GET로 설정하고, URL 입력!

- insert 기능에서 이어서 진행! (참고 : https://sorktjrrb.tistory.com/142)

- 겟(GET)딜리트(DELETE) 타입은 바디(Body)를 따로 입력하지 않는다!

- 전체 데이터를 가지고 올때는 offset과 limit를 설정해서 25개씩만 가져오도록 설정하는게 페이지 구성에 좋기 때문에 이를 설정해서 가져오도록 하자

- Paramsoffsetlimit라는 키를 생성하고 값은 각각 0, 25로 설정 (URL 에도 추가한 offset 과 limit가 동작되도록 작성해 주어야함 http://127.0.0.1:5000/recipes?offset=0&limit=25 )

 

# VSCode에서 API 코드 작성!

- recipe.py 파일 안에 레시피를 가져오는(select) 코드문 작성

- 중간 중간 print() 문을 계속 활용해서 디버깅용으로 혹시 문제가 발생되면 print가 실행된 부분까지는 정상 동작이 된것이므로 그 이후를 기준으로 수정하면 된다! 그러므로 pritn()문 계속 중간 검토용으로 사용!

 
# 우선 코드 작성에 필요한 라이브러리를 import
from flask import request
from flask_restful import Resource

# MySQL DB와 연동하기 위한 라이브러리
from mysql_connection import get_connection
from mysql.connector import Error

# 클래스 생성! 파라미터에는 Resource를 입력해준다. (상속 받기 위해)
class RecipeListResource(Resource) :
    # 전체 레시피를 가져오는 API
    def get(self) :

        # 1. 클라이언트가 보낸 데이터가 있으면 받아준다. 
        # 하지만 셀렉트문은 따로 클라이언트가 보낼 데이터가 없이 요청에 전체 리스트만 보여주면되므로 작성 필요없음
        # postman에서 생성하였던 것처럼 갯수제한을 두기 위해
        # request.args를 사용하여 변수를 생성 이것만 해당 부분에 미리 작성
        offset = request.args['offset']
        limit = request.args['limit']

        print(offset, limit)

        # 2. DB로부터 데이터를 가져온다.
        # 숫자로 지정하는게 아니라 변수로 지정한 offset과 limit를 범위값에 직접 작성 (형태는 정해진 규칙)
        # 클라이언트(유저)가 수정하여 보낼 지칭되는 데이터(튜플 형태)가 없으므로 record는 사용하지 않아도됨
        try :
           
            connection = get_connection()

            query = '''select *
                        from recipe
                        limit '''+offset+''', '''+limit+''';'''
            # record = () 레코드 필요 없음.
 
            ### 중요! select 문은 전체 데이터를 저장된 데이터 형태로 보여주기 때문에 (튜플 형태임 보기가 힘듬)
            ### 클라이언트(유저)가 좀더 보기 쉬운 딕셔너리 형태로 보여주기 위해서
            ### dictionary=True를 cursor의 파라미터안에 작성해 준다!
            
            cursor = connection.cursor(dictionary=True)

            cursor.execute( query )
 
            ### 중요! 쿼리 결과의 모든행을 가져오기 위해.cursor.fetchall() 사용 결과는 리스트로 반환
            ### 위에서 cursor를 딕셔너리 형태로 생성하였기 때문에 리스트의 각 요소는 딕셔너리 형태로 반환
            ### 결국 두가지 모두 쿼리 결과를 다루기 쉽고, 읽기 쉬운 형태로 처리하도록 하는것!
            result_list = cursor.fetchall()

            print(result_list)

            cursor.close()
            connection.close()

        except Error as e :
            if cursor is not None:
                cursor.close()
            if connection is not None:
                connection.close()
            return {'result' : 'fail', 'errer' : str(e)}, 500

        # 3. 클라이언트에 json 만들어서 응답한다. => 문자와 숫자로만 구성하여 보내야 한다.
        ### 중요! DB에서 가져온 timestamp는 python에서 datetime으로 자동 변환되는데
        ### 문제는, datetime은 json 형태로 보낼수가 없다! 문자와 숫자로만 구성해야 하기 때문에!
        ### 따라서, 시간을 문자열로 변환해서 보내주어야 한다.
        i = 0
        for row in result_list :
            result_list[i]['created_at'] = row['created_at'].isoformat()
            result_list[i]['updated_at'] = row['updated_at'].isoformat()
            i = i + 1

            print()
            print(result_list)
       
        return {'items' : result_list,
                'count' : len(result_list),
                'result' : 'success'}
 

 

# app.py 파일에 경로와 리소스(API 코드)를 연결하는 코드도 작성!

 
# API를 처리하는 코드는
# Resource 클래스를 상속받아서 작성한다.
# 이 클래스에는 get, post, put, delete 함수를 상속받는다.
# 따라서 이 함수들을, 우리의 서비스에 맞게 수정해서 사용하면된다.

from flask import Flask
from flask_restful import Api
# 생성한 API class 사용을위해서 생성시마다 import 필요!
from resources.recipe import RecipeListResource

app = Flask(__name__)
api = Api(app)

# 경로(path)와 리소스(API 코드)를 연결한다.
# <int> flask 문법임 외워야됨
api.add_resource( RecipeListResource , '/recipes')
 

 

# 완료 되었으면 서버 실행 cmd > flask run postman을 실행하여 send!

 

# 포스트맨에 200 OK가 뜨고 VScode cmd 창에도 결과가 잘 출력되는것 확인!

 

2) 레시피를 1개만 가지고 오는 API도 설계해 보자 포스트맨을 실행하여 GET로 설정하고, URL 입력!

- 주의할점!!! 특정한 데이터를 한가지만 지정하여 가져올때는 당연히 유니크한 값인 id 값이 필요

- ID를 지정하여 가지고 올때는 ID 값을 URL 맨뒤/id값 으로 작성하여 가지고 올수 있다.

 

# VSCode에서 API 코드 작성!

- 상단에 전체레시피를 가져오는 코드에 붙여서 작성

- 우선 형식이 조금 다르므로 새로운 class 생성


class RecipeResource(Resource) :
    # 특정 레시피 한개를 가져오는 API
    # self, 레시피 db의 id 값 recipe_id
    def get(self, recipe_id) :
       
        # 1. 클라이언트로부터 데이터를 받는다.
        #  print id값 오류가 있을경우 디버깅(수정)위해 입력
        print(recipe_id)

        # 2. DB로 부터 데이터를 가져온다.
        # 위의 recipe_id 에 해당하는 데이터를 가져온다.
        try :
            connection = get_connection()

            # 디버깅 (수정) 과정은 print 문으로 중간 중간 확인 하는것
            # 프린트 문이 출력되는 부분까지 문제가 없는거고, print가 실행되지 않는 그 부분이 문제가있는문구인것
            print('커넥션 실행')

            query = '''select *
                    from recipe
                    where id = %s;'''
 
            # 튜플을 단독값으로 넣을땐 , 꼭 추가해줘야 한다! 이런거 기억할것!!!
            record = (recipe_id,)
            print(record)
 
            # 실행 확인되면 dictionary=True 추가
            cursor = connection.cursor(dictionary=True)

            print('커서 가져오기 성공')

            cursor.execute(query, record)

            print('쿼리문 실행')

            result_list = cursor.fetchall()
            print(result_list)

            cursor.close()
            connection.close()


        except Error as e:
            if cursor is not None:
                cursor.close()
            if connection is not None:
                connection.close()
            return {'result' : 'fail',
                    'error' : str(e)}, 500

        # 3. 응답할 데이터를 JSON으로 만든다.
        i = 0
        for row in result_list :
            result_list[i]['created_at'] = row['created_at'].isoformat()
            result_list[i]['updated_at'] = row['updated_at'].isoformat()
            i = i + 1

        if len(result_list) == 1 :
            return {"item" : result_list[0],
                    "result" : "success"}
        else :
            return {"result": "fail",
                    "error" : "해당 아이디는 존재하지 않습니다."}, 400

 

# app.py 파일에 경로와 리소스(API 코드)를 연결하는 코드도 작성!

 
# API를 처리하는 코드는
# Resource 클래스를 상속받아서 작성한다.
# 이 클래스에는 get, post, put, delete 함수를 상속받는다.
# 따라서 이 함수들을, 우리의 서비스에 맞게 수정해서 사용하면된다.

from flask import Flask
from flask_restful import Api
 
# 생성한 API class 사용을위해서 생성시마다 import 필요!
from resources.recipe import RecipeListResource, RecipeResource

app = Flask(__name__)
api = Api(app)

# 경로(path)와 리소스(API 코드)를 연결한다.
# <int> flask 문법임 외워야됨
# URL에 입력하였던 id 값을 경로로 작성할때는 <int:id 명칭> 형식으로 입력
api.add_resource( RecipeListResource , '/recipes')
api.add_resource( RecipeResource , '/recipes/<int:recipe_id>')

if __name__ == '__main__' :
    app.run()
 

 

# 확인 및 테스트는 위에서 실행했던 방법과 동일하게 동작해보고 200 OK 확인!

 

다음 게시글로 계속~!

 

반응형