RestAPI로 sqlite 데이타베이스 테이블 User를 다루어보자.
Flask와 Flask-Restless로 RestAPI를 구현하고
SQLAlchemy로 테이블 User를 모델로 정의하여 다룬다.
테이블 User를 모델로 정의한다는 것은 SQLAlchemy를 이용해 class로 작성한다는 것을 말한다.
User를 모델로 정의한 코드이다.
app = Flask(__name__)
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20))
regDate = db.Column(db.Date)
email = db.Column(db.String(50))
def __init__(self, name, regDate, email):
self.name = name
self.regDate = datetime.datetime.strptime(regDate, "%d%m%Y").date()
self.email = email
먼저 Flask 개발환경 구성을 위해서 설치부터 하자.
$ cat requirement.txt
Flask
Flask-Restless
Flask-SQLAlchemy
$ sudo pip install -r requirement.txt
Flask와 Flask-SQLAlchemy로 RestAPI를 구성하면 웹서버에 들어오는 요청을 정의하여 @app.route에 등록하고 처리하는 부분을 정의해야 한다.
@app.route('/user/', methods = ['GET'])
def index():
return jsonify({'users': User.query.all()})
@app.route('/user/<int:id>/')
def get_user(id):
return jsonify({'user': User.query.get(id)})
@app.route('/user/', methods = ['POST'])
def create_user():
if not request.json or not 'name' in request.json:
abort(400)
user = User(request.json.name, request.json.get('regDate', ''), request.json.get('email',''))
db.session.add(user)
db.session.commit()
return jsonify( { 'user': user } ), 201
@app.route('/user/<int:id>', methods = ['DELETE'])
def delete_user(id):
db.session.delete(Users.query.get(id))
db.session.commit()
return jsonify( { 'result': True } )
@app.route('/user/<int:id>', methods = ['PUT'])
def update_user(id):
user = User.query.get(id)
user.name = request.json.get('name', user.name)
user.regDate = request.json.get('regDate',user.name)
user.email = request.json.get('email', user.email)
db.session.commit()
return jsonify( { 'user': user } )
위의 설명한 것을 한번에 정리하면 아래와 같다.
$cat restapi_simple-0.1.py
from flask import Flask, jsonify, abort, request
from flask.ext.sqlalchemy import SQLAlchemy
import os
app = Flask(__name__)
basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.sqlite')
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20))
regDate = db.Column(db.Date)
email = db.Column(db.String(50))
def __init__(self, name, regDate, email):
self.name = name
self.regDate = datetime.datetime.strptime(regDate, "%d%m%Y").date()
self.email = email
@app.route('/user/', methods = ['GET'])
def index():
return jsonify({'users': User.query.all()})
@app.route('/user/<int:id>/')
def get_user(id):
return jsonify({'user': User.query.get(id)})
@app.route('/user/', methods = ['POST'])
def create_user():
if not request.json or not 'name' in request.json:
abort(400)
user = User(request.json.name, request.json.get('regDate', ''), request.json.get('email',''))
db.session.add(user)
db.session.commit()
return jsonify( { 'user': user } ), 201
@app.route('/user/<int:id>', methods = ['DELETE'])
def delete_user(id):
db.session.delete(Users.query.get(id))
db.session.commit()
return jsonify( { 'result': True } )
@app.route('/user/<int:id>', methods = ['PUT'])
def update_user(id):
user = User.query.get(id)
user.name = request.json.get('name', user.name)
user.regDate = request.json.get('regDate',user.name)
user.email = request.json.get('email', user.email)
db.session.commit()
return jsonify( { 'user': user } )
if __name__ == '__main__':
db.create_all()
app.run()
Flask로 RestAPI를 정의하는 대신에 Flask-RestLess를 통해 정의 해보았다.
@app.route 부분이 사라지고 APIManager로 대체한다.
# Create the Flask-Restless API manager.
manager = APIManager(app, flask_sqlalchemy_db=db)
# Create API endpoints, which will be available at /api/<tablename> by
# default. Allowed HTTP methods can be specified as well.
manager.create_api(User, methods=['GET', 'POST', 'DELETE'])
한 파일로 정리하면 다음과 같다.
$cat restapi_simple-0.2.py
from flask import Flask, jsonify, abort, request
from flask.ext.restless import APIManager
from flask.ext.sqlalchemy import SQLAlchemy
import os
basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.sqlite')
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')
app = Flask(__name__)
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20))
regDate = db.Column(db.Date)
email = db.Column(db.String(50))
def __init__(self, name, regDate, email):
self.name = name
self.regDate = datetime.datetime.strptime(regDate, "%d%m%Y").date()
self.email = email
# Create the database tables.
db.create_all()
# Create the Flask-Restless API manager.
manager = APIManager(app, flask_sqlalchemy_db=db)
# Create API endpoints, which will be available at /api/<tablename> by
# default. Allowed HTTP methods can be specified as well.
manager.create_api(User, methods=['GET', 'POST', 'DELETE'])
if __name__ == '__main__':
app.run()
인프라가 코딩되고 있다. 그러한 흐름에 적응하기 위해서 엔지니어는 자신의 인프라를 코딩할수 있어야 한다. 짧은 코드를 통해 익숙해졌으면 한다. 처음 가는 길이라 이리저리 헤매는 것이 당연하듯 자주 가는 길은 눈 감고도 간다. 실제로 눈감고 걷다가 도로 한가운데 중앙선을 걸고 있는 나를 발견하기도 했지만, 그런 만용도 줄 수 있는다는 게 익숙하다는 느낌, 이것만큼은 해봤다는 경험이다. 몇줄도 안된다. 경험해보라.
안녕하세요 🙂 유용한 글을 잘읽었습니다. 제가 지금 Flask를 이용해서 rest web server를 만들고 있습니다.
위에 주신 코드로 post와 전체리스트를 불러오는 get을 구현했는데요. post를 통해 database로 값이 전송이 되지만, get을 요청하면 “TypeError: is not JSON serializable” 이렇게 에러가 발생합니다… 이 부분을 어떻게 수정해야되는지 조언을 듣고싶습니다 ㅜ foodsksms@gmail.com – 김재연 –