์ƒˆ์†Œ์‹

Languages/Python

[flask] Do it ์ ํ”„ ํˆฌ ํ”Œ๋ผ์Šคํฌ _ 2. ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ ๋ฐ ๊ฐœ๋… ์ดํ•ด

  • -
๋ฐ˜์‘ํ˜•

์ถœ์ฒ˜ :https://wikidocs.net/81044


์ถœ์ฒ˜ : https://velog.io/

ํ•ด๋‹น ์ž๋ฃŒ ๋ฐ ์‹ค์Šต์€ ๋ชจ๋‘ ์œ„ํ‚ค๋…์Šค(์ ํ”„ ํˆฌ ํ”Œ๋ผ์Šคํฌ) ๋‚ด์šฉ์„ ์ฐธ๊ณ  ํ›„ ์ž‘์„ฑํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.


 

 

* ์•„๋ž˜๋Š” ๊ฐ ํŒŒ์ผ์ด ์–ด๋– ํ•œ ๊ธฐ๋Šฅ์„ ํ•˜๋Š”์ง€ ๋‚˜ํƒ€๋‚ธ ๊ฒƒ์ด๋‹ค. (์ถœ์ฒ˜ : ์œ„ํ‚ค๋…์Šค)

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” models.py ํŒŒ์ผ

ํŒŒ์ด๋ณด ํ”„๋กœ์ ํŠธ๋Š” ORM(object relational mapping)์„ ์ง€์›ํ•˜๋Š” ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋„๊ตฌ์ธ SQLAlchemy๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. SQLAlchemy๋Š” ๋ชจ๋ธ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค. ์ง€๊ธˆ์€ ๋ชจ๋ธ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค๋Š” ๋ง์ด ์ดํ•ด๋˜์ง€ ์•Š๊ฒ ์ง€๋งŒ, ์ดํ›„ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด ์ž˜ ์•Œ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค. ์•„๋ฌดํŠผ ์ง€๊ธˆ ์—ฌ๋Ÿฌ๋ถ„์ด ์•Œ์•„์•ผ ํ•  ๋‚ด์šฉ์€ ํŒŒ์ด๋ณด ํ”„๋กœ์ ํŠธ์—๋Š” "๋ชจ๋ธ ํด๋ž˜์Šค๋“ค์„ ์ •์˜ํ•  models.py ํŒŒ์ผ์ด ํ•„์š”ํ•˜๋‹ค"๋Š” ๊ฒƒ์ด๋‹ค.

 

์„œ๋ฒ„๋กœ ์ „์†ก๋œ ํผ์„ ์ฒ˜๋ฆฌํ•˜๋Š” forms.py ํŒŒ์ผ

ํŒŒ์ด๋ณด ํ”„๋กœ์ ํŠธ๋Š” ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ์„œ๋ฒ„๋กœ ์ „์†ก๋œ ํผ์„ ์ฒ˜๋ฆฌํ•  ๋•Œ WTForms๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. WTForms ์—ญ์‹œ ๋ชจ๋ธ ๊ธฐ๋ฐ˜์œผ๋กœ ํผ์„ ์ฒ˜๋ฆฌํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ํผ ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•  forms.py ํŒŒ์ผ์ด ํ•„์š”ํ•˜๋‹ค.

 

ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•˜๋Š” views ๋””๋ ‰ํ„ฐ๋ฆฌ

pybo.py ํŒŒ์ผ์— ์ž‘์„ฑํ–ˆ๋˜ hello_pybo ํ•จ์ˆ˜์˜ ์—ญํ• ์€ ํ™”๋ฉด ๊ตฌ์„ฑ์ด์—ˆ๋‹ค. views ๋””๋ ‰ํ„ฐ๋ฆฌ์—๋Š” ๋ฐ”๋กœ ์ด๋Ÿฐ ํ•จ์ˆ˜๋“ค๋กœ ๊ตฌ์„ฑ๋œ ๋ทฐ ํŒŒ์ผ๋“ค์„ ์ €์žฅํ•œ๋‹ค. ํŒŒ์ด๋ณด ํ”„๋กœ์ ํŠธ์—๋Š” ๊ธฐ๋Šฅ์— ๋”ฐ๋ผ main_views.py, question_views.py, answer_views.py ๋“ฑ์˜ ๋ทฐ ํŒŒ์ผ์„ ๋งŒ๋“ค ๊ฒƒ์ด๋‹ค.

 

CSS, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ, ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ์ €์žฅํ•˜๋Š” static ๋””๋ ‰ํ„ฐ๋ฆฌ

static ๋””๋ ‰ํ„ฐ๋ฆฌ๋Š” ํŒŒ์ด๋ณด ํ”„๋กœ์ ํŠธ์˜ ์Šคํƒ€์ผ์‹œํŠธ(.css), ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ(.js) ๊ทธ๋ฆฌ๊ณ  ์ด๋ฏธ์ง€ ํŒŒ์ผ(.jpg, .png) ๋“ฑ์„ ์ €์žฅํ•œ๋‹ค.

 

HTML ํŒŒ์ผ์„ ์ €์žฅํ•˜๋Š” templates ๋””๋ ‰ํ„ฐ๋ฆฌ

templates ๋””๋ ‰ํ„ฐ๋ฆฌ์—๋Š” ํŒŒ์ด๋ณด์˜ ์งˆ๋ฌธ ๋ชฉ๋ก, ์งˆ๋ฌธ ์ƒ์„ธ ๋“ฑ์˜ HTML ํŒŒ์ผ์„ ์ €์žฅํ•œ๋‹ค. ํŒŒ์ด๋ณด ํ”„๋กœ์ ํŠธ๋Š” question_list.html, question_detail.html๊ณผ ๊ฐ™์€ ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•  ๊ฒƒ์ด๋‹ค.

 

ํŒŒ์ด๋ณด ํ”„๋กœ์ ํŠธ๋ฅผ ์„ค์ •ํ•˜๋Š” config.py ํŒŒ์ผ

config.py ํŒŒ์ผ์€ ํŒŒ์ด๋ณด ํ”„๋กœ์ ํŠธ์˜ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•œ๋‹ค. ํŒŒ์ด๋ณด ํ”„๋กœ์ ํŠธ์˜ ํ™˜๊ฒฝ๋ณ€์ˆ˜, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋“ฑ์˜ ์„ค์ •์„ ์ด ํŒŒ์ผ์— ์ €์žฅํ•œ๋‹ค.

 

 

#ํ”Œ๋ผ์Šคํฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํŒฉํ† ๋ฆฌ

ํ”Œ๋ผ์Šคํฌ๋Š” app ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์„ค์ •์„ ์ง„ํ–‰ํ•œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ app ๊ฐ์ฒด๋ฅผ ์ „์—ญ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœ์ ํŠธ ๊ทœ๋ชจ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ํ™•๋ฅ ์ด ๋†’์•„์ง„๋‹ค. ์ˆœํ™˜ ์ฐธ์กฐ(circular import) ์˜ค๋ฅ˜๊ฐ€ ๋Œ€ํ‘œ์ ์ด๋‹ค.

์ˆœํ™˜ ์ฐธ์กฐ๋ž€ A ๋ชจ๋“ˆ์ด B ๋ชจ๋“ˆ์„ ์ฐธ์กฐํ•˜๊ณ  B ๋ชจ๋“ˆ์ด ๋‹ค์‹œ A ๋ชจ๋“ˆ์„ ์ฐธ์กฐํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๋งํ•œ๋‹ค.

 

app ๊ฐ์ฒด๋ฅผ ์ „์—ญ์œผ๋กœ ์‚ฌ์šฉํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ์˜ˆ๋ฐฉํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ? ํ”Œ๋ผ์Šคํฌ ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€์—์„œ๋Š” "์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํŒฉํ† ๋ฆฌ(application factory)๋ฅผ ์‚ฌ์šฉํ•˜๋ผ"๊ณ  ๊ถŒํ•œ๋‹ค.

 

# pybo.py๋ฅผ __init__.py ํŒŒ์ผ๋กœ ๋ณ€๊ฒฝ

ํ”Œ๋ผ์Šคํฌ ๊ธฐ๋ณธ ์•ฑ์„ FLASK_APP=pybo๋กœ ์„ค์ •ํ•˜๋ฉด, ๊ธฐ์กด์— pybo๋Š” ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— ์žˆ๋Š” pybo.py ํŒŒ์ผ์„ ๊ฐ€๋ฆฌ์ผฐ์ง€๋งŒ,
๋˜ ๋‹ค๋ฅด๊ฒŒ pybo ๋ชจ๋“ˆ ์ฆ‰ pybo/__init__.py ํŒŒ์ผ์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

pybo.py ์™€ pybo/__init__.py๋Š” ๋™์ผํ•œ pybo ๋ชจ๋“ˆ์ด๋‹ค.

๋”ฐ๋ผ์„œ pybo.py ํŒŒ์ผ์„ pybo/__init__.py ํŒŒ์ผ๋กœ ๋ฐ”๊พธ์–ด๋„ ์˜ค๋ฅ˜์—†์ด ์ž˜ ๋™์ž‘ํ•œ๋‹ค.

์ •์ƒ์œผ๋กœ flask run ์‹คํ–‰

 

# ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํŒฉํ† ๋ฆฌ

from flask import Flask

def create_app():
    app = Flask(__name__)
    @app.route('/')
    def hello_pybo():
        return 'string test'

    return app

create_app ํ•จ์ˆ˜๊ฐ€ app ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด ๋ฐ˜ํ™˜ํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ–ˆ๋‹ค. ์ด๋•Œ app ๊ฐ์ฒด๊ฐ€ ํ•จ์ˆ˜ ์•ˆ์—์„œ ์‚ฌ์šฉ๋˜๋ฏ€๋กœ hello_pybo ํ•จ์ˆ˜๋ฅผ create_app ํ•จ์ˆ˜ ์•ˆ์— ํฌํ•จํ–ˆ๋‹ค. ๋ฐ”๋กœ ์—ฌ๊ธฐ์„œ ์‚ฌ์šฉ๋œ create_app ํ•จ์ˆ˜๊ฐ€ ๋ฐ”๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํŒฉํ† ๋ฆฌ๋‹ค.

ํ•จ์ˆ˜๋ช…์œผ๋กœ create_app ๋Œ€์‹  ๋‹ค๋ฅธ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๋ฉด ์ •์ƒ์œผ๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.
create_app์€ ํ”Œ๋ผ์Šคํฌ ๋‚ด๋ถ€์—์„œ ์ •์˜๋œ ํ•จ์ˆ˜๋ช…์ด๋‹ค.

 

# ๋ผ์šฐํŒ… ํ•จ์ˆ˜ 

hello_pybo ํ•จ์ˆ˜๋Š” / URL๊ณผ ๋งคํ•‘๋˜๋Š” ํ•จ์ˆ˜์ธ๋ฐ, ์ด๋Ÿฌํ•œ URL ๋งคํ•‘์„ @app.route('/')๋ผ๋Š” ์• ๋„ˆํ…Œ์ด์…˜์ด ๋งŒ๋“ค์–ด ์ค€๋‹ค. ์ด๋•Œ @app.route์™€ ๊ฐ™์€ ์• ๋„ˆํ…Œ์ด์…˜์œผ๋กœ URL์„ ๋งคํ•‘ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋ผ์šฐํŒ… ํ•จ์ˆ˜๋ผ๊ณ  ํ•œ๋‹ค.

 

 

# ORM

ORM(object relational mapping)์„ ์ด์šฉํ•˜๋ฉด ํŒŒ์ด์ฌ ๋ฌธ๋ฒ•๋งŒ์œผ๋กœ๋„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค.
์ฆ‰, ORM์„ ์ด์šฉํ•˜๋ฉด ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฟผ๋ฆฌ๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ORM์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ํ…Œ์ด๋ธ”์„ ํŒŒ์ด์ฌ ํด๋ž˜์Šค๋กœ ๋งŒ๋“ค์–ด ๊ด€๋ฆฌํ•˜๋Š” ๊ธฐ์ˆ ๋กœ ์ดํ•ดํ•ด๋„ ์ข‹๋‹ค.

 

๋น„๊ตํ•˜์ž๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Œ

insert into question (subject, content) values ('์•ˆ๋…•ํ•˜์„ธ์š”', '๊ฐ€์ž… ์ธ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค ^^');

question1 = Question(subject=’์•ˆ๋…•ํ•˜์„ธ์š”’, content='๊ฐ€์ž… ์ธ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค ^^')
db.session.add(question1)

์œ„ Insert ๋ฌธ์€ ๊ธฐ์กด์˜ sql ์ด๊ณ , ์•„๋ž˜ question1์ด๋ผ๋Š” ๋ณ€์ˆ˜ ์•ˆ ์ฟผ๋ฆฌ๋ฌธ์ด ORM์ด๋‹ค.

# ORM ์žฅ์ 
1. ORM์„ ์ด์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ข…๋ฅ˜์— ์ƒ๊ด€ ์—†์ด ์ผ๊ด€๋œ ์ฝ”๋“œ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์–ด์„œ ํ”„๋กœ๊ทธ๋žจ์„ ์œ ์ง€·๋ณด์ˆ˜ํ•˜๊ธฐ๊ฐ€ ํŽธ๋ฆฌํ•˜๋‹ค. 
2. ๋‚ด๋ถ€์—์„œ ์•ˆ์ „ํ•œ SQL ์ฟผ๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด ์ฃผ๋ฏ€๋กœ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋‹ฌ๋ผ๋„ ํ†ต์ผ๋œ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
3. ์˜ค๋ฅ˜ ๋ฐœ์ƒ๋ฅ ๋„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

4. ํŒŒ์ด์ฌ๋งŒ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค. ๋“ฑ๋“ฑ..

 

# ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜

Flask-Migrate ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•˜๋ฉด SQLAlchemy๋„ ํ•จ๊ป˜ ์„ค์น˜๋˜๋ฏ€๋กœ myproject ๊ฐ€์ƒ ํ™˜๊ฒฝ์—์„œ ๋‹ค์Œ ๋ช…๋ น์„ ์ˆ˜ํ–‰ํ•˜์—ฌ Flask-Migrate ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•˜์ž.

# ์„ค์ •ํŒŒ์ผ ์ถ”๊ฐ€

flask_project ์•„๋ž˜์˜ 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 ๋Š” : 
๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘์† ์ฃผ์†Œ

SQLALCHEMY_TRACK_MODIFICATIONS๋Š” :
SQLAlchemy์˜ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์˜ต์…˜์ด๋‹ค. ์ด ์˜ต์…˜์€ ํŒŒ์ด๋ณด์— ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ False๋กœ ๋น„ํ™œ์„ฑํ™” ํ•œ๋‹ค.

SQLALCHEMY_DATABASE_URI :
์„ค์ •์— ์˜ํ•ด SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์‚ฌ์šฉ๋˜๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํŒŒ์ผ์€ ํ”„๋กœ์ ํŠธ ํ™ˆ ๋””๋ ‰ํ„ฐ๋ฆฌ ๋ฐ”๋กœ ๋ฐ‘์—  pybo.db ํŒŒ์ผ๋กœ ์ €์žฅ๋œ๋‹ค.

#๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ดˆ๊ธฐํ™”

๋จผ์ € 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) #config ํŒŒ์ผ์„ ์ฝ๊ธฐ ์œ„ํ•จ์ž„

    # ORM
    db.init_app(app)
    migrate.init_app(app, db)

    # ๋ธ”๋ฃจํ”„๋ฆฐํŠธ
    from .views import main_views
    app.register_blueprint(main_views.bp)

    return app



'''
    ์ด๋ถ€๋ถ„์ด ๊ธฐ์กด์˜ route๋ถ€๋ถ„์ธ๋ฐ, ๋ธ”๋ฃจํ”„๋ฆฐํŠธ๋กœ view๋กœ ๋”ฐ๋กœ ๋บ์Œ
    @app.route('/')
    def hello_pybo():
        return 'string test'
'''

 

์ดํ›„ flask db init  ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ดˆ๊ธฐํ™” ํ•ด์ค€๋‹ค.

๊ทธ๋Ÿผ ์•„๋ž˜์™€ ๊ฐ™์ด migrations ๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ๊น€

์˜ค๋ฅธ์ชฝ์— DB๋ช…๋ น์–ด 2๊ฐœ๋Š” ๊ผญ ์™ธ์šฐ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

 

# data base query ์ž‘์„ฑํ•˜๊ธฐ

pybo ์•„๋ž˜ models.py๋ฅผ ์ƒ์„ฑ ํ›„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•œ๋‹ค.  ๊ฐ ์ฝ”๋“œ์— ๋Œ€ํ•œ ์„ค๋ช…์€ > https://wikidocs.net/81045 ์ฐธ๊ณ ํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

 

2-04 ๋ชจ๋ธ๋กœ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌํ•˜๊ธฐ

`[์™„์„ฑ ์†Œ์Šค]` : [github.com/pahkey/jump2flask/tree/2-04](https://github.com/pahkey/jump2flask/tree/2 ...

wikidocs.net

from pybo import db

# ์งˆ๋ฌธ ๋ชจ๋ธ
class Question(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    subject = db.Column(db.String(200), nullable=False) # nullable์€ ๋นˆ ๊ฐ’์˜ ๋Œ€ํ•œ ํ—ˆ์šฉ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ false๋Š” ๋นˆ ๊ฐ’์ด ๋ถˆํ—ˆํ•˜๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.
    content = db.Column(db.text(), nullable=False)
    create_data = 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)

์ž‘์„ฑ ํ›„ ์ ์šฉํ•ด์ค€๋‹ค. 

> flask db migrate

์ ์šฉ ์‹œ, ef96 ~~ ๋ผ๊ณ  ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ณ€๊ฒฝ ์ž‘์—…์„ ์œ„ํ•œ ๋ฆฌ๋น„์ „ ํŒŒ์ผ์ด ์ƒ์„ฑ๋œ๋‹ค.

๋ฆฌ๋น„์ „(revision)์ด๋ž€ ์ƒ์„ฑ๋œ ํŒŒ์ผ์—์„œ .py ํ™•์žฅ์ž๋ฅผ ์ œ์™ธํ•œ ef96.._์™€ ๊ฐ™์€ ๋ฒ„์ „ ๋ฒˆํ˜ธ๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

๋ฆฌ๋น„์ „์€ flask db migrate ๋ช…๋ น์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ๋ฌด์ž‘์œ„๋กœ ๋งŒ๋“ค์–ด์ง„๋‹ค.

์ด์–ด์„œ flask db upgrade ๋ช…๋ น์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ ๋ฆฌ๋น„์ „ ํŒŒ์ผ์„ ์‹คํ–‰ํ•˜์ž. (๋ฆฌ๋น„์ „ ํŒŒ์ผ ๋‚ด์—๋Š” ํ…Œ์ด๋ธ” ์ƒ์„ฑ์„ ์œ„ํ•œ ์ฟผ๋ฆฌ๋ฌธ๋“ค์ด ์ €์žฅ๋˜์–ด ์žˆ๋‹ค.) -> pybo.db๊ฐ€ ์ƒ์„ฑ๋จ => pybo.db๊ฐ€ ๋ฐ”๋กœ SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฐ์ดํ„ฐ ํŒŒ์ผ์ด๋‹ค.

๋ฐ˜์‘ํ˜•
Contents

ํฌ์ŠคํŒ… ์ฃผ์†Œ๋ฅผ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค

์ด ๊ธ€์ด ๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด ๊ณต๊ฐ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.