2-3.모델로 데이터 처리하기

2021. 8. 6. 13:58Mobile App

 

웹서비스는 데이터를 처리할 때 대부분 데이터베이스를 사용한다. 

데이터를 SQL쿼리 문으로 데이터베이스에 저장하거나 불러올 수 있다.

구조화된 질의를 작성하고 실행하는 등 복잡한 과정이 필요한데, ORM을 이용하면 파이썬 문법만으로도 데이터베이스를 다룰 수 있다.

ORM을 이용하면

=>별도의 SQL문법을 배우지 않아도 된다는 장점이 있다.

=>데이터베이스 종류에 상관 없이 일관된 코드를 유지할 수 있어서 프로그램을 유지, 보수하기가 편리하다.

=>내부에서 안전한 SQL 쿼리를 자동으로 생성해주므로 개발자가 달라도 통일된 쿼리를 작성할 수 있고, 오류 발생률도 줄일 수 있다.

 

[플라스크 ORM라이브러리 사용하기]

1) ORM 라이브러리 설치하기

Flask-Migrate 라이브러리를 설치하면 SQLAlchemy도 함께 설치되므로 파이썬 가상환경에서 Flask-Migrate라이브러리를 설치해야한다!

pip install Flask-Migrate 명령어 입력!

근데 이건 윈도우 한정 명령어 !

아나콘다는 또다름 !

 

2) 설정 파일 추가하기

import os

BASE_DIR = os.path.dirname(__file__)

SQLALCHEMY_DATABASE_URI = 'sqlite:///{}'.format(os.path.join(BASE_DIR,'pybo.db')) #데이터 베이스 접속주소
SQLALCHEMY_TRACK_MODIFICATIONS = False #SQLAlchemy 이벤트 처리 옵션 (비활성화)

 

지금 설정한 내용은 pybo.db라는 데이터 베이스 파일을 프로젝트의 루트 디렉터리에 저장하려는 것이다.

SQLite란?

파이썬 기본 패키지에 포함된 주로 소규모에 프로젝트에서 사용하는 가벼운 파일을 기반으로 한 데이터 베이스이다.

개발을 빠르게 진행할 수 있게 도와준다.(이후 실제 운영시 규모가 더 큰 데이터베이스로 변경해서 사용하기도 함)

 

3)ORM 적용하기

pybo/__init__.py파일을 수정해 SQLAlchemy를 적용하자,

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)
	#블루프린트
	from .views import main_views
	app.register_blueprint(main_views.bp)
	
	return app

 

 

4)데이터베이스 초기화하기

flask db init명령으로 데이터베이스를 초기화할 것이다.

flask db init 이 명령어는 데이터베이스를 관리하는 초기 파일들을 migrations라는 디렉터리에 자동으로 생성해 준다. 이때 생성되는 파일들은 Flask-Migrate라이브러리에서 사용된다. 파일 내용은 알필요 없음

이 명령어는 최초 한번만 수행하면된다 .

 

 

[모델 만들기]

여기서 모델이란? 데이터를 다룰 목적으로 만든 파이썬 클래스

질문 답변 게시판을 만들 것이기 때문에, 질문과 답변에 해당하는 모델이 있어야한다.

1) 모델 속성 구상하기

모델 속성은 모델의 종류에 따라 달라진다. 

 

2)질문 모델 생성하기

구상한  속성을 바탕으로 모델을 정의한다. 아 위치는 pybo/models.py이다. 

from pybo import db

class Question(db.Model):	#모델정의, 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)

내가 정의한 질문모델인 Question클래스이다. 모든 모델의 기본 클래스인 db.Model을 상속받았다. 

db는 __init__.py파일에서 생성한 SQLAlchemy객체이다. 

각 속성은 db.Column 클래스를 사용해 생성했다.

속성의 데이터타입, 속성을 기본키로 지정할 것인지, 속성에 빈값을 허용할 것인지 등의 옵션을 지정해준다.

 

3)답변 모델 생성하기

질문모델과 같은 위치의 파일에 생성해준다. 

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)

 

 

 

[모델을 이용해 테이블 자동으로 생성하기]

1) 모델 가져오기

pybo/__init__.py파일에서 #ORM부분을 수정하자,

	#ORM
	db.init_app(app)
	migrate.init_app(app,db)
	from . import models    #migrate 객체가 models.py파일을 참조하게 함

생성한 모델들을 플라스크의 Migrate기능이 인식할 수 있어짐

 

 

2) 데이터베이스 변경을 위한 리비전 파일 생성하기

데이터베이스가 변경되도록 명령 프롬프트에서 flask db migrate명령을 수행하야한다.

데이터 베이스 변경을 처리할 리비전 파일이 생성된다.  위 명령어를 수행할 때 무작위로 만들어 지는 것.

 

3) 데이터베이스 갱신하기

flask db upgrade 명령으로 리비전 파일을 실행하자.

 

pybo.db 파일이 생성되었다. 이게 바로SQLite 데이터베이스의 데이터 파일이다.

 

 

[생성된 테이블 살펴보기]

pybo.db데이터 파일에 정말로 question과 answer 테이블이 생성되었는지 확인하자.

SQLite의 GUI도구인 DB Browser for SQLite를 사용한다.

https://sqlitebrowser.org/dl/ 에서 

standart installer를 설치하면 된다. 

 

옵션도 체크해주자

 

설치가 완료된 뒤 실행한다. 파일-> 데이터베이스 열기를 선택하고, 앞에서 생성한 pybo.db데이터베이스 파일을 선택한다.

pybo.db안에 answer, question 테이블이 생성되었음을 확인할 수 있다.

 

[모델 사용하기]

모델도 만들었고, 모델을 기반으로 테이블도 생성했으니 이제 모델을 사용할 차례이다.

1)플라스크 셸 실행하기

밑의 모든 명령어는 플라스크 셸에 입력하는 것이다 !!

flask shell 명령어로 실행할 수 있다. 

플라스크 셸은 플라스크를 실행하는데 필요한 환경이 자동으로 설정되어 실행된다. 

2)질문데이터 저장하기

다음 명령으로 Question과 Answer 모델을 플라스크 셸에 불러오자. 그런다음 Question모델 객체를 하나 생성할 것.

>>> from pybo.models import Question, Answer
>>> from datetime import datetime
>>> q=Question(subject='pybo가 무엇?',content='pybo에 대해 알고싶다',create_date=datetime.now())

Question 클래스를 사용하기 위해 subject, content, create_date 정보가 포함되어야한다.

객체 q를 만들었다고해서 데이터베이스에 저장되는 것은 아니다.

 

 

데이터베이스에 저장하려면 다음처럼 SQLAlchemy의 db객체를 사용해야한다.

>>> from pybo import db
>>> db.session.add(q)
>>> db.session.commit()

신규 데이터를 저장할 떄는 add함수를 사용한 다음, commit함수까지 실행해야한다.

db.session은 데이터베이스와 연결된 세션, 즉 접속된 상태를 의미한다. 데이터베이스를 처리하려면 이 세션이 필요하다.

주의, 커밋은 취소할 수 없다. 수행한 작업을 취소하려면 커밋 이전에 진행해야한다. 

이때 작업을 취소하고 싶으면 db.session.rollback 함수로 되돌리기를 실행하면 된다. 

 

 

id는 question모델의 기본키 이다. 자동으로 1씩 증가하는 것

증가한다!

 

 

3)데이터 조회하기

 

Question.query.all()

 

Question.query.filter(Question.id==1).all()

 

 

>>> Question.query.get(1)

Question에 유일한 값이 있으면 사용할 수 있음

여기서 유일한 값은 id이다.

 

 

Question.query.filter(Question.subject.like('%모델%')).all()

Question모델의 subject 속성에 '모델'문자열이 포함된 데이터를 조회한 것

대소문자 구분하지 않으려면 like 대신 ilike 함수 사용!

a% a로 시작하는 문자열
%a a로 끝나는 문자열
%a% a를 포함하는 문자열

 

 

4)데이터 수정하기

데이터를 수정할 때는 단순히 대입 연산자를 사용하면 된다. 

subject 속성을 수정했다. 반드시 커밋까지 !!

 

5)데이터 삭제하기

첫번째 question을 삭제하자.

>>> q = Question.query.get(1)
>>> db.session.delete(q)
>>> db.session.commit()
>>> Question.query.all()

q에 id1번 질문을 넣어놓음!

delete함수를 사용해서 첫번째 질문 삭제!

반드시 커밋까지!

모든 질문을 조회해본 결과 : Question2만 나온다!

 

 

6)답변 데이터 생성 후 저장하기

>>> from datetime import datetime
>>> from pybo.models import Question,Answer
>>> from pybo import db

>>> q = Question.query.get(2) 	#2번 질문 대입
>>> a = Answer(question=q, content='자동생성됩니다. ', create_date=datetime.now()) #2번 질문에 답변 남김
>>> db.session.add(a)	
>>> db.session.commit()

 

 

 

Answer 모델의 question 속성에 역참조 설정 backref=db.backref('answer_set') 을 적용했다.

그러므로 이를 사용하면 질문과 연결된 답변을 쉽게 가져올 수 있다.

아직 역참조 설정의 유용함을 별로 느끼지 못하지만, 개발자에게 큰 편의를 가져다주는 기능이라고 함. 

 

 

데이터베이스 관리 명령어 설명
flask db init 데이터베이스 초기화(최초 한번만 실행)
flask db migrate 모델을 생성하거나 변경
flask db upgrade 모델의 변경 내용을 실제 데이터베이스에 적용
flask db 명령어 종류 확인하기
db.session.add(q)
db.session.commit()
데이터베이스에 신규데이터q 저장하기
db.session.delete(q)
db.session.commit()
데이터베이스에 데이터q 삭제하기
 db.session.rollback  작업취소하기
db이름.query.all() 데이터 조회하기
#리스트 반환
db이름.query.filter(db이름.id==n).all() id값이 n인 데이터만 조회
#id==n이 필터링 조건이 되는 것
db이름.query.get(n) 유일한 값이 n인것 조회
#여기서는 id가 유일한 값임

 

 

 

 

 

 

'Mobile App' 카테고리의 다른 글

인증  (0) 2021.08.24
API와 HTTP의 관계  (0) 2021.08.09
2-2.블루프린트로 라우트 함수 관리하기  (0) 2021.08.05
2-1.플라스크 애플리케이션 팩토리  (0) 2021.08.04
1.플라스크 개발준비  (0) 2021.08.04