#4. 데이타베이스 모델작업 및 Resource 제작

FirstValue·2023년 3월 16일
0
post-thumbnail

4.1 데이타베이스 모델 작업

SQLAlchemy는 Python에서 사용가능한 ORM(Object-Relational Mapping) 이며,객체와 관계형 데이터베이스의 데이터를 자동으로 매핑(연결)해주는 것을 말한다.
여기서는 Flask에서 확장형태로 SQLALchemy을 지원하는 Flask-SQLALchemy 라이브러리를 사용한다.


⌘ db_init.py ( 위치: linkservice/server/db_init.py)


db_init.py는 db = SQLAlchemy() 선언을 해주는 공통 모듈로 활용 한다

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()


이제부터 DB 테이블 LINKS에 맞는 DB모델을 제작하고, 기본적인 id 값으로 삭제/조회/업데이트 등 필요한 기본 METHOD을 정의한다

from db_init import db
from sqlalchemy import func

class LinkModel(db.Model):
# DB 스키마가 기본(public)이 아니면 별도로 선언을 해주면 된다.
    __table_args__ = {'schema': 'aip'}
# 물리 테이블명
    __tablename__ = "links"
# 컬럼 맵핑
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100))
    tag = db.Column(db.String(50))
    sort = db.Column(db.Integer)
    imageurl = db.Column(db.Text)
    linkurl = db.Column(db.Text)
    create_date = db.Column(db.Date)
    update_date = db.Column(db.Date)

    def __init__(self, id, name, tag, sort, imageurl, linkurl, create_date,update_date):
        self.id = id
        self.name = name
        self.tag = tag
        self.sort = sort
        self.imageurl = imageurl
        self.linkurl = linkurl
        self.create_date = create_date
        self.update_date = update_date

    def save(links):
        """
        정보 저장/수정
        :param 정보 객체
        """
        db.session.merge(links)
        db.session.commit()
        db.session.close()

# Link정보 저장시 sort 순서의 max값을 구한다. 만약 null이면 0 으로 변경
    @classmethod
    def max_sort(self):
      result = db.session.query(func.coalesce(func.max(self.sort), 0)).scalar()

      return result+1

# 기본적인 조회/삭제/업데이트 코드를 구성한다. ( param : id )
    @classmethod
    def find_by_id(self, id):

        links= db.session.query(self).filter_by(id=id).first()
        return links

    @classmethod
    def delete_by_id(self, id):
      try:
        db.session.query(self).filter_by(id=id).delete(synchronize_session=False)
      except:
        db.session.rollback()
      finally:
        db.session.commit()
        db.session.close()

    @classmethod
    def update_by_id(self, id, values):
        db.session.query(self).filter_by(id=id).update(values)     
        db.session.commit()   
        db.session.close()     

    def __str__(self):
        return "[" + str(self.__class__) + "]: " + str(self.__dict__)

DB모델과 기본 정보 조회/삭제/업데이트 관련 메소드도 제작이 끝났으니,
이젠 API 형태로 제공하고자 Resource을 제작한다.

4.2. Resource 제작


⌘ links.py ( 위치: linkservice/server/src/links.py)


links.py에서 API 호출 시 실행되는 class을 정의해보자.

  • class LinkRegister(Resource) : 링크정보를 DB에 등록(Insert) 한다.
  • class LinksAll(Resource) : 전체 링크 정보를 조회한다.
  • class LinkSelect(Resource) : 선택한 링크정보를 조회 한다.
  • class LinkRemove(Resource) : 선택한 링크정보를 삭제 한다.
  • class LinkUpdate(Resource) : 선택한 링크정보를 수정 한다.
from db_init import db
from flask_restful import Resource, reqparse
from flask import jsonify, request
from flask_marshmallow import Marshmallow
from models.links_model import LinkModel
from datetime import date as date_function

ma = Marshmallow() #객체를 Python 데이터 유형으로 직렬화

class LinkSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = LinkModel

"""
POST /api/link/create -  등록 resource
"""
class LinkRegister(Resource):
# 입력 파라미터 설정
# DB항목에 맞게 파라메타로 받아 저장한다.
    parser = reqparse.RequestParser()
    parser.add_argument('name',type=str,required=True,help="필수항목입니다.")
    parser.add_argument('tag',type=str)
    parser.add_argument('sort',type=str)     
    parser.add_argument('imageurl',type=str )      
    parser.add_argument('linkurl',type=str )    

    def post(self):
        # Request Parameter를 dictionary 형태로 저장
        data = LinkRegister.parser.parse_args()
        name = data['name']
        tag = data['tag']
        sort = LinkModel.max_sort() #Sort순서를 위한 값으로 입력시 max값을 입력한다.
        imageurl = data['imageurl']
        linkurl = data['linkurl']
        create_date = date_function.today()  #create_date는 datetime으로 저장
        update_date = date_function.today()

        LinkModel.save(LinkModel(None, name, tag, sort, imageurl, linkurl, create_date, update_date))

        return {'message':f'링크 정보가 등록 되었습니다'},201

"""
GET /api/links - 전체 링크정보 조회
"""

class LinksAll(Resource):

    def get(self):
    # 입력 파라미터 설정 - 목록전체 출력으로 파라미터가 없음.
        link = LinkModel.query.order_by(LinkModel.sort).all()
        link_schema = LinkSchema(many=True)
        output = link_schema.dump(link)
        return jsonify({'links' : output})

"""
GET /api/link/select/<int:id> - 링크 정보 조회
"""
class LinkSelect(Resource):

    def get(self,id):
        # 정보 조회
        link = LinkModel.find_by_id(id)
        link_schema = LinkSchema()
        output = link_schema.dump(link)
        return jsonify({'links' : output})

"""
DELETE /api/link/delete/<int:id> - 링크정보삭제
"""
class LinkRemove(Resource):
    def delete(self, id):
        # 정보 삭제 ( links_model의 delete_by_id 메소드 호출 )
        LinkModel.delete_by_id(id)

        return {'message':'정상적으로 삭제 되었습니다.'},201

"""
PUT /api/link/update/<int:id> - 링크 정보 수정
"""
class LinkUpdate(Resource):

    def put(self,id):
        #Request를 json으로 받는다.
        values = request.get_json()
        # 정보 수정 ( links_model의 update_by_id 메소드 호출 )
        LinkModel.update_by_id(id, values)
        return {'message':'정보가 수정 되었습니다.'},201

다음 편에는 server.py에 flask_restful에서 제공되는 API Resource을 추가해 보자.

✓ 참고자료

>> Sqlalchemy

>> Flask + marshmallow for beautiful APIs


profile
개발은 개~발이 아니길 바라는 아재

0개의 댓글