[오늘의 배움] 006 플라스크 블루프린트와 ORM

이상민·2020년 11월 29일
0

[오늘의 배움]

목록 보기
6/70
post-thumbnail

1. 블루프린트

url마다 라우트 함수를 추가해줘야 한다면 매우 번거롭고 관리하기도 힘들 것이다. 이 때문에 블루프린트 클래스를 사용한다. 블루프린트를 쓰면 라우트 함수를 구조적으로 관리할 수 있다.

1-1. 블루프린트 객체 생성

from flask import Blueprint

bp = Blueprint('main', __name__, url_prefix='/')


@bp.route('/')
def hello_pybo():
    return 'Hello, Pybo!'

__init__.py의 라우트 함수를 main_views.py에 옮긴것이다. 블루프린트 객체를 생성할 때는 (이름, 모듈명, url 프리픽스값)이 인자로 들어간다.

1-2. 블루프린트 등록

__init__.py의 create_app()에 블루프린트를 다음과 같이 등록한다.

from flask import Flask


def create_app():
    app = Flask(__name__)
    
    from .views import main_views
    app.register_blueprint(main_views.bp)
    
    return app

블루프린트를 적용했으니 라우트 함수에 url을 등록한다. 각 url로 가면 함수가 잘 실행되는것을 볼 수 있다.

from flask  import Blueprint

bp = Blueprint('main', __name__, url_prefix='/')

@bp.route('/hello')
def hello_pybo():
    return 'Hello, Pybo!'


@bp.route('/')
def index():
    return 'Pybo index'

2. ORM

데이터베이스를 사용할때 sql로 질의하지 않고 파이썬 문법만으로도 데이터베이스를 다룰 수 있게해주는 것이 ORM(Object Relational Mapping)이다.

2-1. ORM 라이브러리

sql 삽입예

insert into question (subject, content) values ('안녕하세요', '가입 인사드립니다 ^^');
insert into question (subject, content) values ('질문 있습니다', 'ORM이 궁금합니다');

orm 삽입 예

question1 = Question(subject=’안녕하세요’, content='가입 인사드립니다 ^^')
db.session.add(question1)
question2 = Question(subject=’질문 있습니다’, content='ORM이 궁금합니다')
db.session.add(question2)

파이썬에서 많이 사용하는 ORM라이브러리는 SQLAlchemy이다. Flask-Migrate라이브러리는 파이썬 모델을 이용해 테이블을 생성하고 컬럼을 추가할 수 있게 해준다. pip으로 간단히 설치가능하다.

2-2. ORM 적용

ORM을 적용하려면 config.py 설정 파일이 필요하다. 프로젝트 루트 디렉토리에 생성하고 다음 코드를 작성한다. SQLCHEMY_DATABASE_URI는 DB 접속 주소이고, SQLALCHEMY_TRACK_MODIFICATIONS는 SQLAlchemy의 이벤트 처리 옵션이다.

import os

BASE_DIR = os.path.dirname(__file__)

SQLALCHEMY_DATABASE_URI = 'sqlite:///{}'.format(os.path.join(BASE_DIR, 'pybo.db'))
SQLALCHEMY_TRACK_MODIFICATIONS = False

__init__.py를 수정해 SQLAlchemy를 적용한다. db와 migrate객체는 다른 함수에서도 쓸 수 있게 전역으로 선언하고 함수 내에서 초기화한다.

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

import config
db = SQLAlchemy()
migrate = Migrate()


def create_app():
    app = Flask(__name__)
    app.config.from_object(config)
    
    # ORM
    db.init_app(app)
    migrate.init_app(app, db)

    # Blueprint
    from .views import main_views
    app.register_blueprint(main_views.bp)

    return app

3. 모델

데이터를 관리하는데 사용하는 ORM 클래스를 모델이라고 하는데 RDB에서 테이블과 비슷한 개념인것 같다.

3-1. 데이터베이스 초기화와 모델 추가/변경

터미널에서 데이터베이스를 초기화한다. 명령어 실행 시 데이터베이스 관리를 위한 초기 파일을 migrations 디렉토리에 자동으로 생성한다. 이 파일들은 Flask-Migrate 라이브러리에서 사용되므로 내용을 딱히 알 필요는 없다.

flask db init

모델을 추가하거나 변경할때 다음 명령어로 처리할 수 있다.

flask db migrate # 모델을 새로 생성/변경
flask db upgrade # 모델 변경 내용을 DB에 적용 

3-2. 모델 만들기

플라스크에서 데이터 타입이 Integer이고 기본키인 애트리뷰트는 튜플이 추가될 때 자동으로 1씩 증가한다고 한다.

질문 모델과 답변 모델

from pybo import db


class Question(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    subject = db.Column(db.String(200), nullable=False)
    content = db.Column(db.Text(), nullable=False)
    create_date = db.Column(db.DateTime(), nullable=False)


class Answer(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    question_id = db.Column(db.Integer, db.ForeignKey('question.id', ondelete="CASCADE"))
    question = db.relationship('Question', backref=db.backref('answer_set'))
    content = db.Column(db.Text(), nullable=False)
    create_date = db.Column(db.DateTime(), nullable=False)

.Column으로 애트리뷰트를 설정할 수 있고 .ForeignKey로 외부 키를 설정할 수 있다.
.relationship은 다른 모델을 참조하게 할 수 있다. 위의 예에서는 answer.question.subject와 같이 참조 가능하다. 이때 역참조 설정을 할 수 있는데 question.answer_set으로 질문에서 답변을 참조할 수 있게한다.

db.Column(데이터형, 옵션)
db.ForeignKey(연결할 속성명, 연동 설정)
db.relationship(참조할 모델, 역참조 설정)
profile
편하게 읽기 좋은 단위의 포스트를 추구하는 개발자입니다

0개의 댓글