ORM(object relational mapping) 방식
데이터베이스에 데이터를 저장하는 테이블을 파이썬 클래스로 만들어 관리하는 기술이다.
개발자가 쿼리를 직접 작성하지 않아도 데이터베이스의 데이터를 처리할 수 있다.
쿼리를 이용한 새 데이터 삽입 예
insert into question (subject, content) values ('안녕하세요', '가입 인사드립니다 ^^');
ORM을 이용한 새 데이터 삽입 예
question1 = Question(subject=’안녕하세요’, content='가입 인사드립니다 ^^')
db.session.add(question1)
데이터베이스 종류에 상관 없이 일관된 코드를 유지할 수 있어 프로그램 유지 보수가 쉼다.
ORM 라이브러리 설치 (Flask-Migrate)
(myproject) c:\projects\myproject>pip install flask-migrate
파이썬 모델을 이용해 테이블을 생성하고 컬럽을 추가하는 작업을 할 수 있게 해주는 라이브러리
설정 파일 추가하기
[projects\myproject\config.py]
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_DATABASE_URI : 데이터 베이스 접속 주소
SQLite 데이버테이스가 사용되고, 데이터베이스 파일은 프로젝트 홈 디렉터리 바로 밑 pybo.db 파일로 저장된다.
SQLALCHMY_TRACK_MODIFICATIONS : SQLAlchemy의 이벤트를 처리하는 옵션
ORM 적용하기
[projects\myproject\pybo\__init__.py]
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
app.config.from_object(config)
config.py 파일에 작성한 항목을 읽기 위한 코드다.
db = SQLAlchemy()
migrate = Migrate()
전역 변수로 db, migrate 객체를 만들고 create_app 함수 안에서 init_app 메서드를 이용해 app에 등록한다.
db 객체를 create_app 함수 안에서 생성하면 블루프린트와 같은 다른 모듈에서 사용할 수 없으므로 전역 변수로 선언한다.
데이터베이스 초기화하기
(myproject) c:\projects\myproject>flask db init
flask db init
데이터베이스를 관리하는 초기 파일들을 migrations 디렉터리에 자동으로 생성한다.
데이터베이스 관리 명령어
flask db migrate : 모델을 새로 생성하거나 변경할 때 사용
flask db upgrade : 모델의 변경 내용을 실제 데이터베이스에 적용할 때 사용
질문 모델 생성
[projects\myproject\pybo\models.py]
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)
속성명 | 설명 |
id | 질문 데이터의 고유 번호 |
subject | 질문 제목 |
content | 질문 내용 |
create_date | 질문 작성일시 |
모델 클래스는 db.Model 클래스를 상속하여 만들어야 한다.
여기서의 db 객체는 __init__.py 파일에서 생성한 SQLAlchemy 클래스의 객체다.
각 속성은 db.Column으로 생성한다.
db.Column()
첫 번째 인수는 데이터의 타입을 의미한다.
- db.Integer : 숫자 값
- db.String : 글자 수가 제한된 텍스트
- db.Text : 글자 수를 제한할 수 없는 텍스트
- db.DateTime : 날짜와 시각
추가적인 속성
- primary_key : id 속성을 기본 키로 설정 (중복된 값을 가질 수 없게 만든다)
- nullable : 값을 저장할 때 빈 값을 허용할지 여부 (디폴트 값은 빈 값 허용)
답변 모델 생성
[projects\myproject\pybo\models.py]
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)
속성명 | 설명 |
id | 답변 데이터의 고유 번호 |
question_id | 질문 데이터의 고유 번호 |
content | 답변 내용 |
create_date | 답변 작성일시 |
question_id = db.Column(db.Integer, db.ForeignKey('question.id', ondelete='CASCADE'))
question_id 속성은 답변과 질문을 연결하기 위한 속성이다.
답변은 어떤 질문에 대한 답변인지 알아야 하므로 질문의 id 속성이 필요하다.
모델을 서로 연결하기 위해서는 db.ForeignKey(외부 키)를 사용해야 한다.
db.ForeignKey()
첫 번째 파라미터 'question.id'는 question 테이블의 id 컬럼을 의미한다.
Question 모델을 통해 생성된 테이블명은 question이다.
두 번째 파라미터 ondelete는 삭제 연동 설정이다.
ondelete='CASCADE'는 질문을 삭제하면 해당 질문에 달린 답변도 함꼐 삭제된다.
question = db.relationship('Question', backref=db.backref('answer_set'))
db.relationship으로 question 속성을 생성하면 answer.question.subject처럼 답변 모델에서 질문 모델을 참조할 수 있다.
db.relationship()
첫 번째 파라미터는 참조할 모델명이고
두 번째 backref 파라미터는 역참조 설정이다.
역참조? 질문에서 답변을 거꾸로 참조하는 것을 의미한다.
어떤 질문에 해당하는 객체가 a_question이라면 a_question.answer_set 처럼 질문에 달린 답변들을 참조할 수 있다.
'Backend > Server' 카테고리의 다른 글
[Flask] 질문 목록과 상세 기능 (0) | 2023.07.31 |
---|---|
[Flask] 데이터 처리하기 (DB) (2) (0) | 2023.07.31 |
[Flask] 블루프린트 (0) | 2023.07.27 |
[Flask] 플라스크 애플리케이션 팩토리 (0) | 2023.07.26 |
[Flask] 플라스크 서버 실행하기 (0) | 2023.07.26 |