[flask] mysql+ORM(flask_sqlalchemy)+REST API

깨미·2021년 7월 15일
0

Flask

목록 보기
2/9
post-thumbnail
post-custom-banner

flask에서 mysql 연동까지 완성됐고, 이제 db를 REST API로 CRUD 연산이 가능하고자 한다😁

REST API 정의 및 생성

db 스키마 작성

먼저 db 스키마를 python 에서 class화 시킨다.
아주 아주 간단한 group_table을 만들었다.

#table_group.py

from backend_model.database import DBManager

db = DBManager.db #flask_sqlalchemy로 db를 관리하기 위해 정의한 class / db = SQLAlchemy(app) 로 선언돼있음. 
class group_table(db.Model):
    __tablename__ = 'group_table'

    id = db.Column('id', db.Integer, primary_key=True)
    groupname = db.Column('groupname', db.String(24), comment='그룹이름')
    permission = db.Column('permission', db.Integer, comment='권한') # 0: admin 1: user

🎈 사족 : 이런 ORM을 다루고 나니 아주 아주 간편해졌다.. 학부생때는 mysql 에서 일일히 db table 다 만들어놓고 php로 힘들게 다루었던 기억이 ^^.. 그때는 모든 게 다 익숙치 않아서 하드 코딩 했던거 같다 😂

RES API 정의

그런 다음 route를 이용하여 URI 별 api들을 정의한다.
나는 group_table에 데이터를 추가하는 api를 정의했다.

#api_group.py

db = DBManager.db 
@app.route('/api/efwb/v1/group_table', methods=['POST']) #여기서 app은 app = Flask(__name__) 로 선언돼 있음.
def group_post_api():
    data = json.loads(request.data) # 요청 data 가져오기

    params = ['groupname', 'permission'] # tabla column 체크

    for param in params:
        if param not in data:
            return make_response(jsonify('Parameters are not enough.'), 400)



    group = group_table()

    group.groupname = data['groupname']
    group.permission = data['permission']


    db.session.add(group) # db에 추가
    db.session.commit()   # commit

    result = {
      "result": "OK"
    }

    return make_response(jsonify(result), 200)

REST API 생성

이제 api까지 정의했다면 group_table을 rest api로 통신할 수 있도록 api endpoint를 생성한다.

#api_create.py

from flask_restless import APIManager

# api
manager = APIManager(app, flask_sqlalchemy_db=DBManager.db)
manager.create_api(group_table
                   , url_prefix='/api/v1'
                   , methods=['GET', 'DELETE', 'PATCH', 'POST'])

rest api를 사용할 때 url 정의와 header, token 정의가 중요하다.
나는 header 정의는 따로 하지 않았는데, 이후 보안을 위해서는 header를 따로 정의해야 한다.

flask start, API 통신 확인

이렇게 만들고 python main.py로 flask를 구동시키고, postman으로 내가 정의한 api가 제대로 동작하는 지 확인한다.

[flask start]

postman 사용

postman은 여기서 설치할 수 있다.
https://www.postman.com/

설치하고 나면 Home에서 Workspaces를 눌러 새로운 workspace를 만든다.

여기 APIs 에서

HTTP Request로 이동하면 rest api 통신이 제대로 되는 지 확인할 수 있다.
python에서 정의한 url을 입력하고, body에서 raw로 json 내용을 입력하여 send를 보낸다.

HTTPStatus.BAD_REQUEST

그럼 아래와 같은 에러가 발생하는데,

[포스트맨에서 발생한 에러]

127.0.0.1 - - [15/Jul/2021 17:39:06] code 400, message Bad request version ('À\x13À')
127.0.0.1 - - [15/Jul/2021 17:39:06] "÷ó§1:¬ZÝ~
                                               x¸mǦ4VlÌ+RwÚ,Yc´kôÖ ÑuÌʸò&{*%Ér³Y¥ùNpÏ|*$À/À+À0À,̨̩À
À" HTTPStatus.BAD_REQUEST -

[flask 구동 에서 발생한 에러]

http로 통신해야 하는데 https로 통신했기 때문에 발생한 에러이다.

sqlalchemy.exc.ProgrammingError: (MySQLdb._exceptions.ProgrammingError) (1146)

http로 수정하여 send하였는데

    _mysql.connection.query(self, query)
sqlalchemy.exc.ProgrammingError: (MySQLdb._exceptions.ProgrammingError) (1146, "Table 'table.group_table' doesn't exist")
[SQL: INSERT INTO group_table (groupname, permission) VALUES (%s, %s)]
[parameters: ('한사랑요양원', 0)]
(Background on this error at: http://sqlalche.me/e/f405)

이런 오류가 나왔다. group_table을 mysql에서 생성하지 않았기 때문이다.

flask_sqlalchemy로 db를 관리하기 위해 정의한 DBManager에서 group_table의 sample 데이터를 넣는 함수를 생성하고, manage.py에서 이 함수를 실행하는 script를 만든 다음, manage.py를 구동하여 쉽게 db table을 만든다. manage.py에 대한 내용은 해당 글을 통해 확인할 수 있다.

#DBManager

    def insert_dummy_group_table():
        print("insert_dummy_group_table")
        from backend_model.table_user import group_table

        group = group_table()

        group.groupname = "hello"
        group.permission = 0


        DBManager.db.session.add(group)

        DBManager.db.session.commit()
        
# manage.py
@manager.command
def insert_group():
    if check_message('Are you sure to insert data ? (Y/n)') == False:
        return
    with app.app_context():
        DBManager.insert_dummy_group_table()

그런 다음, 다시 http request로 post를 보내니

성공적으로 post request를 받아 db data가 추가됐고,

또 postman 에서도 성공적으로 response를 받은 것을 확인할 수 있다.

profile
vis ta vie
post-custom-banner

0개의 댓글