#5. Python์ผ๋ก API ๊ฐ๋ฐ(๊ธฐ๋ณธํ๊ฒฝ๊ตฌ์ฑ)
#5. Python์ผ๋ก API ๊ฐ๋ฐ(๊ธฐ๋ณธํ๊ฒฝ๊ตฌ์ฑ)
โ server.py ( ์์น: linkservice/server/server.py) --------------------------------------------------------------------------------------------------- app.py๋ก ๋ณดํต ๋ช ์นญ ํ์ง๋ง, ์ฌ๊ธฐ์๋ server.py๋ก ๋ค์์ ๋ณ๊ฒฝํ์ฌ ์งํํ๋ค. ์ค
firstvalue.tistory.com
Python Flask์ ๊ธฐ๋ณธํ๊ฒฝ์ด ๊ตฌ์ฑ๋์๊ณ , ์ด์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๋ จ ์์ ์ ์งํํ๋ค.
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()
โ links_model.py ( ์์น: linkservice/server/models/links_model.py)
---------------------------------------------------------------------------------------------------
์ด์ ๋ถํฐ 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 ์ผ๋ก ๋ณ๊ฒฝ
# ํ๋ฉด์ ์ถ๋ ฅ๋๋ ์์๋ฅผ ๋ณ๊ฒฝํ๊ธฐ sortํญ๋ชฉ์ด ํ์ํ๋ฉฐ, ๋งํฌ์ ๋ณด ๋ฑ๋ก์ max๊ฐ์ ์ ์ฅํ๊ธฐ์ํด์ ํ์
@classmethod
def max_sort(self):
result = db.session.query(func.coalesce(func.max(self.sort), 0)).scalar()
return result+1
# ๊ธฐ๋ณธ์ ์ธ ์กฐํ/์ญ์ /์
๋ฐ์ดํธ ์ฝ๋๋ฅผ ๊ตฌ์ฑํ๋ค. ( param : id )
@classmethod
# id๋ก ์กฐํ
def find_by_id(self, id):
links= db.session.query(self).filter_by(id=id).first()
return links
@classmethod
# id๋ก ์ญ์
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
# id๋ก values๊ฐ์ ์
๋ฐ์ดํธ
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__)
Links ํ ์ด๋ธ์ DB๋ชจ๋ธ๊ณผ ๊ธฐ๋ณธ ์ ๋ณด ์กฐํ/์ญ์ /์ ๋ฐ์ดํธ ๊ด๋ จ ๋ฉ์๋๋ ์ ์์ด ๋๋ฌ์ผ๋,
์ด์ API ํํ๋ก ์ ๊ณตํ๊ณ ์ Resource๋ฅผ ์ ์ํ๋ค.
1.1. 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
์ฐธ๊ณ ์๋ฃ :
ORM Quick Start — SQLAlchemy 2.0 Documentation
ORM Quick Start For new users who want to quickly see what basic ORM use looks like, here’s an abbreviated form of the mappings and examples used in the SQLAlchemy Unified Tutorial. The code here is fully runnable from a clean command line. As the descri
docs.sqlalchemy.org
Flask + marshmallow for beautiful APIs
Flask-Marshmallow: Flask + marshmallow for beautiful APIs — Flask-Marshmallow 0.14.0 documentation
Flask-Marshmallow: Flask + marshmallow for beautiful APIs changelog // github // pypi // issues Flask + marshmallow for beautiful APIs Flask-Marshmallow is a thin integration layer for Flask (a Python web framework) and marshmallow (an object serialization
flask-marshmallow.readthedocs.io
๋ค์ ํธ์๋ server.py์ flask_restful์์ ์ ๊ณต๋๋ API Resource์ ์ถ๊ฐํด ๋ณด์.
'React&Python์ผ๋ก ์น๊ฐ๋ฐ > ๋งํฌ์๋น์ค' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
#7. ํ๋ก ํธ์๋ ํ๋ฉด ๊ฐ๋ฐ (0) | 2023.03.16 |
---|---|
#6. Python์ผ๋ก API ๊ฐ๋ฐ(API Resource์ ์ธ ๋ฐ ํ ์คํธ) (0) | 2023.03.11 |
#5. Python์ผ๋ก API ๊ฐ๋ฐ(๊ธฐ๋ณธํ๊ฒฝ๊ตฌ์ฑ) (0) | 2023.03.09 |
#5. Python์ผ๋ก API ๊ฐ๋ฐ (0) | 2023.03.09 |
#4. ํ๋ก์ ํธ ํด๋ ๊ตฌ์กฐ ๋ฐ ํ๊ฒฝ์ค์ (0) | 2023.03.09 |