플라스크폴더구조에 해당하는 글 1

플라스크 팩토리 패턴으로 바꾸기

Computer 관심/Flask|2022. 1. 13. 00:12
반응형

플라스크는 하나에 파이썬 파일에 서버를 쉽게 만들 수 있다. 

엄청 간단한 기능을 만들거나 테스트앱을 만들때 간단히 하나의 파일로 만들면 빠르게 개발 할 수 있다. 

하지만 조금만 앱의 크기가 커지면 하나의 파일로 코드를 작성하는게 불편해 지는 때가 온다.

 

팩토리 패턴을 사용하여 파일을 나눌 수 있다.

 

일단 참고한 사이트는 아래의 사이트이다. 사이트에 어떻게 나누어야 하는지 아주 자세하게 잘 나와있다. 

https://wikidocs.net/81044

 

2-01 플라스크 기초 다지기

현재 파이보 프로젝트는 `projects/myproject` 디렉터리 아래에 pybo.py 파일만 생성한 상태다. 그런데 이보다 규모를 갖춘 플라스크 프로젝트를 만들고자 한 ...

wikidocs.net

 

간략하게 설명한다면

1. 파이썬 메인 파일을 __init__.py로 바꾸어 폴더 통체로 모듈화를 한다

2. views 폴더를 만들어서 url을 적고

3. models.py를 만들어서 모델을 넣는다. 

 

이걸 하는 동안 작은 문제가 발생했는데 다음과 같다.

시작과 함게 디비를 만드는 db.create_all()이 에러를 발생했고 

 

 

__init__.py파일 안에 아래와 같이 코드를 만들었더니 디비가 생성되지 않는 에러가 나타났다. 그런데 

def create_app():


    with app.app_context():
            db.create_all()
            
    from .views import main_views
    app.register_blueprint(main_views.bp)
    return app

 

아래 처럼

with app.app_context():

      db.create_all()

을 맨 마지막에 적으니 작동이 된다. 

 

def create_app():
	
    
    from .views import main_views
    app.register_blueprint(main_views.bp)
    
    with app.app_context():
    	db.create_all()  
    return app

 

 

코드 나눈건 아래 같은 방식으로 나누었다.

 

__init__.py

from flask import Flask
from flask_cors import CORS
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy

# *** 중요 (팩토리 패턴세팅) ***
db = SQLAlchemy()
migrate = Migrate()

# ***** 팩토리 패턴에서 자동으로 실행되는 create_app() 함수 
def create_app():
    app = Flask(__name__)
    CORS(app)

    app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///inventory.db" # sqllite
    # app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://로컬유저네임:로컬비번@localhost/default'
    # app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://닉네임:비밀번호@파이썬애니웨어닉네임.mysql.pythonanywhere-services.com/디비네임$default'
    app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {'pool_recycle': 280}
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

    UPLOAD_FOLDER = './downloads'
    
    # *** 중요 (팩토리 패턴세팅) ***
    app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
    db.init_app(app)
    migrate.init_app(app, db)

    from .views import main_views
    app.register_blueprint(main_views.bp)
	
    with app.app_context():
        db.create_all()

    
    return app

 

 

views.py

# *** 중요 (팩토리 패턴세팅): Blueprint 임포트하기 ***
from flask import Blueprint
from flask import request
import pandas as pd
from myapp import db
from myapp.models import ProductInfo, Quots, SalesDetail, StockLevel, Sales, Purchase, Bom, QuotsDetail, PurchaseDetail
import json
from werkzeug.utils import secure_filename
from flask import make_response

# *** 중요 (팩토리 패턴세팅): url 경로 / 기준으로 엔드포인트 만듬 ***
bp = Blueprint('main', __name__, url_prefix='/')

@bp.route("/add_product_info", methods=['GET', 'POST'])
def add_product_info():
    if request.method == 'POST':
        objects = []
     	...
        return '0'
    else:
        return '0'


@bp.route("/csv_upload", methods=['POST'])
def csv_upload():
    if request.method == 'POST':
        counts = {'total':0, 'insert': 0, 'update':0}
        if 'file' not in request.files:
            print('No file part')
            
        file = request.files['file']
        if file.filename == '':
            print('No selected file')

        if file and allowed_file(file.filename):
        ...
        
    print('success')        
    return {'stauts':'success', 'counts':counts}


@bp.route("/product_edit", methods=['POST'])
def product_edit():
    if request.method == 'POST':
        row = json.loads(request.data)['data']
         ...
        db.session.commit()
    return {'res':0}

 

 

models.py

# *** 중요 (팩토리 패턴세팅)__init__에 만든 db 가져오기 ***
from myapp import db
import datetime

class ProductInfo(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    article = db.Column(db.String(32), unique=True, nullable=False)
    ...
    #server deafult는 string
    online_shop = db.Column(db.Boolean, nullable=False, server_default='0', default=0)
    stocks = db.relationship("StockLevel")

    def as_dict(self):
        return {c.name: getattr(self, c.name) for c in self.__table__.columns}


class Sales(db.Model):
    __tablename__ = 'sales'
    id = db.Column(db.Integer, primary_key=True)
    ...
    status = db.Column(db.String(16))
    children = db.relationship("SalesDetail")

 

> set FLASK_ENV=development
> flask run

 

댓글()