[Flask] 모델로 데이터 처리하기 - 모델 사용하기
- 웹 프로그래밍
- 2022. 3. 29. 20:50
참조
모델 가져오기
- 앞에서 생성한 모델들을 플라스크의 Migrate 기능이 인식할 수 있도록 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 . import models
# Blueprint
from .views import main_views
app.register_blueprint(main_views.bp)
return app
데이터베이스 변경을 위한 리비전 파일 생성하기
- 이제 명령 프롬프트에서 flask db migrate 명령을 수행합니다.
(myproject) C:\venvs\myproject>flask db migrate
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.autogenerate.compare] Detected added table 'question'
INFO [alembic.autogenerate.compare] Detected added table 'answer'
Generating C:\venvs\myproject\migrations\versions\cc1a2433bfd0_.py ... done
- 이 명령을 수행하면 cc1a2433bfd0_.py 처럼 데이터베이스 변경 작업을 위한 리비전 파일이 생성됩니다.
리비전(revision) 이란 생성된 cc1a2433bfd0_.py 파일명에서 cc1a2433bfd0_을 가리킵니다. 리비전은 flask db migrate 명령을 수행할 때 무작위로 만들어 집니다.
데이터베이스 갱신하기
- 다음으로 flask db upgrade 명령으로 리비전 파일을 실행합니다.
(myproject) C:\venvs\myproject>flask db upgrade
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> cc1a2433bfd0, empty message
- 이 과정에서 데이터베이스에 모델 이름과 똑같은 question과 answer 라는 이름의 테이블이 생성됩니다.
- 지금까지의 동작이 정상 동작 되었으면, venvs/myproject 디렉터리에 pybo.db 파일이 생성되었습니다.
- pybo.db 가 바로 SQLite 데이터베이스의 데이터 파일입니다.
플라스크 셸 실행하기
- 플라스크 셸은 명령 프롬프트에서 flask shell 명령으로 실행합니다.
(myproject) C:\venvs\myproject>flask shell
Python 3.10.2 (tags/v3.10.2:a58ebcc, Jan 17 2022, 14:12:15) [MSC v.1929 64 bit (AMD64)] on win32
App: pybo [development]
Instance: C:\venvs\myproject\var\pybo-instance
>>>
플라스크 셸은 프라스크를 실행하는 데 필요한 환경이 자동으로 설정되어 실행됩니다.
질문 데이터 저장하기
- 다음 명령을 수행해 Question 과 Answer 모델을 플라스크 셸에 불러옵니다.
- 그런 다음 Question 모델 객체를 하나 생성합니다.
>>> from pybo.models import Question, Answer
>>> from datetime import datetime
>>> q = Question(subject='pybo가 무엇인가요?', content='pybo에 대해서 알고 싶습니다.', create_date=datetime.now())
- Question 모델의 create_date 속성은 DateTime 유형이므로 datetiem.now 함수로 현재 일시를 대입했습니다.
- 객체 q 를 만들었다고 해서 데이터베이스에 저장되는 것은 아닙니다.
- 데이터베이스에 저장하려면 다음처럼 SQLAlchemy의 db 객체를 사용해야 합니다.
>>> from pybo import db
>>> db.session.add(q)
>>> db.session.commit()
- 코드에서 보듯 신규 데이터를 저장할 떄는 add 함수를 사용한 다음 commit 함수까지 실행해야 합니다.
- db.session은 데이터베이스와 연결된 세션, 즉 접속된 상태를 의미합니다.
- 데이터베이스를 처리하려면 이 세션이 필요합니다.
- 그리고 세션을 통해서 데이터를 저장, 수정, 삭제 작업을 한 다음에는 반드시 db.session.commit() 으로 커밋을 해줘야 합니다.
- 데이터가 잘 생성되었는지 확인합니다.
>>> q.id
1
- id는 Question 모델의 기본 키 입니다.
- id는 앞서 모델을 생성할 때 설정했던 대로 데이터를 생성할 때 속성값이 자동으로 1씩 증가합니다.
- 실제로 증가하는데 질문 데이터를 생성한 후, id 확인합니다.
>>> q = Question(subject='플라스크 모델 질문입니다.', content='id는 자동으로 생성되나요?', create_date=datetime.now())
>>> db.session.add(q)
>>> db.session.commit()
>>> q.id
2
- id 가 2로 출력된 것을 확인할 수 있습니다.
데이터 조회하기
- 이번에는 데이터베이스에 저장된 데이터를 조회해 봅니다.
>>> Question.query.all()
[<Question 1>, <Question 2>]
- Question.query.all()로 데이터베이스에 저장된 질문 데이터를 전부 조회했습니다.
- 이 함수는 Question 객체 리스트를 반환합니다.
- 결과에서 보이는 숫자 1,2 는 Question 객체의 id 속성값입니다.
>>> Question.query.filter(Question.id==1).all()
[<Question 1>]
- filter 함수는 인자로 전달한 조건에 맞는 데이터를 모두 반환해줍니다.
- 여기서는 기본 키인 id를 이용했으므로 값을 1개만 반환합니다.
- id는 유일한 값이므로 filter 함수 대신 get 함수를 이용해 조회할 수도 있습니다.
>>> Question.query.get(1)
<Question 1>
- 다만 get 함수로 조회하면 리스트가 아닌 Question 객체 1개만 반환됩니다.
데이터 수정하기
- 데이터를 수정할 떄는 단순히 대입 연산자를 사용하면 됩니다.
>>> q = Question.query.get(2)
>>> q
<Question 2>
>>> q.subject = 'Flask Model Question'
>>> db.session.commit()
데이터 삭제하기
- 다음은 데이터 삭제하는 방법입니다.
>>> q = Question.query.get(1)
>>> db.session.delete(q)
>>> db.session.commit()
>>> Question.query.all()
[<Question 2>]
답변 데이터 생성 후 저장하기
- 이번에는 답변(Answer) 데이터를 생성하고 저장합니다.
>>> from datetime import datetime
>>> from pybo.models import Question, Answer
>>> from pybo import db
>>> q = Question.query.get(2)
>>> a = Answer(question=q, content='네 자동으로 생성됩니다.', create_date=datetime.now())
>>> db.session.add(a)
>>> db.session.commit()
>>> a.id
1
>>> a = Answer.query.get(1)
>>> a
<Answer 1>
답변에 연결된 질문 찾기 vs 질문에 달린 답변 찾기
- 앞에서 구성한 Answer 모델의 question 속성을 이용하면 "답변에 연결된 질문" 을 조회할 수 있습니다.
>>> a.question
<Question 2>
- 답변에 연결된 질문 찾기는 Answer 모델에 question 속성이 정의되어 있어서 매우 쉽습니다.
- Question 모델과 Answer 모델은 현재 현결된 상태이고, Answer 모델의 question 속성에 역참조 설정
backref=db.backref('answer_set')
을 적용했습니다.
>>> q.answer_set
[<Answer 1>]
728x90
'웹 프로그래밍' 카테고리의 다른 글
[Flask] 답변 등록 기능 만들기 (0) | 2022.03.30 |
---|---|
[Flask] 질문 목록과 질문 상세 기능 만들기 (0) | 2022.03.30 |
[Flask] 모델로 데이터 처리하기 - SQLAlchemy 설치 (0) | 2022.03.29 |
[Flask] Flask 블루프린트로 라우트 함수 관리하기 (0) | 2022.03.28 |
[Flask] Flask 애플리케이션 팩토리 (0) | 2022.03.28 |
이 글을 공유하기