Skip to content
This repository has been archived by the owner on Feb 22, 2020. It is now read-only.

Commit

Permalink
Merge pull request #29 from somul-project/kujyp/db-migration/180411
Browse files Browse the repository at this point in the history
Kujyp/db migration/180411
  • Loading branch information
kujyp authored Apr 11, 2018
2 parents 5616cf2 + b37bd17 commit d1e0774
Show file tree
Hide file tree
Showing 17 changed files with 408 additions and 178 deletions.
5 changes: 4 additions & 1 deletion .env.sample
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
SECRET_KEY = localsecretkey
DB_HOST= # Blank means localhost
# Blank means localhost
DB_HOST=
DB_USERNAME=root
DB_PASSWORD=
DB_NAME=mydb
DB_PORT=3306
SQLALCHEMY_DATABASE_URI=mysql+pymysql://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?charset=utf8
SQLALCHEMY_TRACK_MODIFICATIONS=True
SQLALCHEMY_ECHO=True
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,13 @@

```
cat ~/.ssh/id_rsa.pub | sudo ssh -i <PEM_FILE_NAME>.pem [email protected] "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys"
```
```


## Database migration 가이드

migrations 스크립트를 수행하려면 터미널에서 아래 명령어 실행
```
export FLASK_APP=wsgi.py
flask db upgrade
```
134 changes: 15 additions & 119 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,129 +1,25 @@
import json
import traceback

from flask import Flask, request, render_template, session
from flask import Flask
from flask_cors import CORS
from flask_migrate import Migrate

from app.v1.controllers.libraries import libraries_api
from app.database import db
from app.database.models import Library
from app.config import Config
from app.v1.controllers.maps import maps_api


app = Flask(__name__)
app.secret_key = Config.secret_key
CORS(app, resources={r"/apply": {"origins": "*"}})
app.register_blueprint(libraries_api, url_prefix='/api/v1')
app.register_blueprint(maps_api, url_prefix='/api/v1')

libraries = db.query(Library)


def register_session(args):
session["name"] = args["name"]
session["location_road"] = args["roadAddress"]
session["location_number"] = args["numberAddress"]
session["location_detail"] = args["detailAddress"]
session["manager_name"] = args["managerName"]
session["manager_email"] = args["managerEmail"]
session["manager_phone"] = args["managerPhone"]
session["audiences"] = args["capacity"]
session["fac_beam_screen"] = 1 if args["facilityBeamOrScreen"] else 0
session["fac_sound"] = 1 if args["facilitySound"] else 0
session["fac_record"] = 1 if args["facilityRecord"] else 0
session["fac_placard"] = 1 if args["facilityPlacard"] else 0
session["fac_self_promo"] = 1 if args["facilitySelfPromo"] else 0
session["fac_other"] = args["facilityOther"]
session["req_speaker"] = args["requirements"]


@app.route("/")
def index():
return render_template("done.html")


@app.route("/success")
def success():
return render_template("success.html")


@app.route("/failure")
def failure():
return render_template(
"failure.html",
name=session.get("name", "정보 없음"),
location_road=session.get("location_road", "정보 없음"),
location_number=session.get("location_number", "정보 없음"),
location_detail=session.get("location_detail", "정보 없음"),
manager_name=session.get("manager_name", "정보 없음"),
manager_email=session.get("manager_email", "정보 없음"),
manager_phone=session.get("manager_phone", "정보 없음"),
audiences=session.get("audiences", "정보 없음"),
fac_beam_screen="가능" if session.get(
"fac_beam_screen", False) else "불가",
fac_sound="가능" if session.get("fac_sound", False) else "불가",
fac_record="가능" if session.get("fac_record", False) else "불가",
fac_placard="가능" if session.get("fac_placard", False) else "불가",
fac_self_promo="가능" if session.get("fac_self_promo", False) else "불가",
fac_other=session.get("fac_other", "정보 없음"),
req_speaker=session.get("req_speaker", "정보 없음")
)


@app.route("/applylist")
def applylist():
try:
return render_template("list.html",
libraries=libraries,
length=len(list(libraries)))
except: # noqa: E722
print(traceback.format_exc())

def create_app(config):
_app = Flask(__name__)
_app.config.from_object(config)
CORS(_app, resources={r"/apply": {"origins": "*"}})

@app.route("/api/v1/apply", methods=["POST"])
def apply():
try:
args = json.loads(request.data.decode('utf-8'))
except: # noqa: E722
print("Invalid Request Payload")
return json.dumps({
"result": -1,
"cause": "Invalid request payload"
})
from app.views import views
_app.register_blueprint(views)

register_session(args)
from app.v1.controllers.libraries import libraries_api
from app.v1.controllers.maps import maps_api

db.add_all([
Library(
name=args["name"],
location_road=args["roadAddress"],
location_number=args["numberAddress"],
location_detail=args["detailAddress"],
manager_name=args["managerName"],
manager_email=args["managerEmail"],
manager_phone=args["managerPhone"],
audiences=args["capacity"],
fac_beam_screen=1 if args["facilityBeamOrScreen"] else 0,
fac_sound=1 if args["facilitySound"] else 0,
fac_record=1 if args["facilityRecord"] else 0,
fac_placard=1 if args["facilityPlacard"] else 0,
fac_self_promo=1 if args["facilitySelfPromo"] else 0,
fac_other=args["facilityOther"],
req_speaker=args["requirements"]
)
])
_app.register_blueprint(libraries_api, url_prefix='/api/v1')
_app.register_blueprint(maps_api, url_prefix='/api/v1')

try:
db.commit()
db.init_app(_app)
Migrate(_app, db)

return json.dumps({
"result": 0
})
except: # noqa: E722
db.rollback()
print("Unexpected DB server error")
return json.dumps({
"result": 1,
"cause": "Unexpected DB server error"
})
return _app
5 changes: 4 additions & 1 deletion app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@ class Config:
db_password = os.environ.get("DB_PASSWORD")
db_name = os.environ.get("DB_NAME")
db_port = int(os.environ.get("DB_PORT"))
db_uri = os.environ.get("SQLALCHEMY_DATABASE_URI")
SQLALCHEMY_DATABASE_URI = os.environ.get("SQLALCHEMY_DATABASE_URI")
SQLALCHEMY_TRACK_MODIFICATIONS\
= bool(os.environ.get("SQLALCHEMY_TRACK_MODIFICATIONS"))
SQLALCHEMY_ECHO = bool(os.environ.get("SQLALCHEMY_ECHO"))
15 changes: 2 additions & 13 deletions app/database/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from app.config import Config
from flask_sqlalchemy import SQLAlchemy

engine = create_engine(Config.db_uri, echo=True, convert_unicode=True)
db = scoped_session(sessionmaker(
autocommit=False, autoflush=False, bind=engine))
Base = declarative_base()
Base.query = db.query_property()


def initialize_database():
Base.metadata.create_all(bind=engine)
db = SQLAlchemy()
53 changes: 28 additions & 25 deletions app/database/models.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,43 @@
from sqlalchemy import Column, Text
from sqlalchemy import Text
from sqlalchemy.dialects.mysql import TINYINT, INTEGER
from sqlalchemy.orm import validates

from app.database import Base
from app.utils.errors import InvalidArgumentError
from app.database import db


class Library(Base):
class Library(db.Model):
__tablename__ = 'Libraries'

_id = Column('id',
INTEGER(11, unsigned=True),
primary_key=True,
autoincrement=True)
name = Column('name', Text)
location_road = Column('location_road', Text)
location_number = Column('location_number', Text)
location_detail = Column('location_detail', Text)

manager_name = Column('manager_name', Text)
manager_email = Column('manager_email', Text)
manager_phone = Column('manager_phone', Text)
audiences = Column('audiences', Text)

fac_beam_screen = Column('fac_beam_screen', TINYINT(1))
fac_sound = Column('fac_sound', TINYINT(1))
fac_record = Column('fac_record', TINYINT(1))
fac_placard = Column('fac_placard', TINYINT(1))
fac_self_promo = Column('fac_self_promo', TINYINT(1))

fac_other = Column('fac_other', Text)
req_speaker = Column('req_speaker', Text)
_id = db.Column('id',
INTEGER(11, unsigned=True),
primary_key=True,
autoincrement=True)
name = db.Column('name', Text)
location_road = db.Column('location_road', Text)
location_number = db.Column('location_number', Text)
location_detail = db.Column('location_detail', Text)

manager_name = db.Column('manager_name', Text)
manager_email = db.Column('manager_email', Text)
manager_phone = db.Column('manager_phone', Text)
audiences = db.Column('audiences', Text)

fac_beam_screen = db.Column('fac_beam_screen', TINYINT(1))
fac_sound = db.Column('fac_sound', TINYINT(1))
fac_record = db.Column('fac_record', TINYINT(1))
fac_placard = db.Column('fac_placard', TINYINT(1))
fac_self_promo = db.Column('fac_self_promo', TINYINT(1))

fac_other = db.Column('fac_other', Text)
req_speaker = db.Column('req_speaker', Text)

@validates('name')
def validate_not_empty(self, key, field):
if not field:
raise InvalidArgumentError("{} must be not empty.".format(key))

return field

def __repr__(self):
return '<Library %r>' % self.name
3 changes: 1 addition & 2 deletions app/v1/controllers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
from flask_restful import reqparse

from app.config import Config
from app.database import db
from app.utils.errors import DataNotFoundError, WrongSecretkeyError


def get_or_404(model_clazz, pk):
instance = db.query(model_clazz).filter_by(_id=pk).first()
instance = model_clazz.query.filter_by(_id=pk).first()
if instance is None:
raise DataNotFoundError(
"{} {} Not found".format(model_clazz.__name__, pk))
Expand Down
24 changes: 12 additions & 12 deletions app/v1/controllers/libraries.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def __init__(self):
super().__init__()

def get(self):
libraries = db.query(Library).all()
libraries = Library.query.all()

resp_fields = library_fields
if get_is_admin():
Expand All @@ -117,15 +117,15 @@ def post(self):
library = Library(**args)

try:
db.add(library)
db.commit()
db.session.add(library)
db.session.commit()
except IntegrityError as e:
print(str(e))
db.rollback()
db.session.rollback()
raise DuplicatedDataError(str(e.orig))
except Exception as e:
print(str(e))
db.rollback()
db.session.rollback()
raise e

return library
Expand Down Expand Up @@ -153,15 +153,15 @@ def put(self, pk):
setattr(library, key, value)

try:
db.merge(library)
db.commit()
db.session.merge(library)
db.session.commit()
except IntegrityError as e:
print(str(e))
db.rollback()
db.session.rollback()
raise DuplicatedDataError(str(e.orig))
except Exception as e:
print(str(e))
db.rollback()
db.session.rollback()
raise e

return library
Expand All @@ -170,11 +170,11 @@ def delete(self, pk):
library = get_or_404(Library, pk)

try:
db.delete(library)
db.commit()
db.session.delete(library)
db.session.commit()
except Exception as e:
print(str(e))
db.rollback()
db.session.rollback()
raise e

return '', 204
Expand Down
6 changes: 3 additions & 3 deletions app/v1/controllers/maps.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from flask_restful import (Resource, fields, marshal_with,
Api)

from app.database import db
from app.database.models import Library

map_fields = {
Expand All @@ -19,10 +18,11 @@ def __init__(self):

@marshal_with(map_fields)
def get(self):
libraries = db.query(Library).all()
libraries = Library.query.all()

for library in libraries:
library.province = library.location_road[0:2]
if library.location_road:
library.province = library.location_road[0:2]

return libraries

Expand Down
Loading

0 comments on commit d1e0774

Please sign in to comment.