2023.07.15 - [Flask] - Flask 이용한 웹사이트 제작기 (2) - 폴더 구조/ hello world 띄우기
sqlite3 module과 flask 연동.
- Connect to the Database
공식 듀토리얼에 나와있는 것 처럼, db.py를 만든 후 flask와 연결할 수 있게 준비한다.
// flaskr/db.py
import sqlite3
import click
from flask import current_app, g
def get_db():
if 'db' not in g:
g.db = sqlite3.connect(
current_app.config['DATABASE'],
detect_types=sqlite3.PARSE_DECLTYPES
)
g.db.row_factory = sqlite3.Row
return g.db
def close_db(e=None):
db = g.pop('db', None)
if db is not None:
db.close()
그런데 저기에 g라는 이상한 걸 import한다. clean code 관점에서 대체 뭐하는건가... 싶은 함수인디. 밑에 자세히 설명이 나와있는데 대충 읽어 보면.. 한 번 연결해 둔 것을 요청 때마다 끊지 않고, 재사용 할 수 있게끔 도와주는 함수인가보다. 그래서 코드를 보면 처음에 g에 db가 없다면 연결해주고, 있다면 바로 return해준다.
그래서 왜 'g' 라고 한 글자만 써뒀을까.... 좀 풀어서좀 써 주지.
current_app은 flask app이 만들어진 후에 생성되는, flask app을 가르키는 또다른 포인터라고 한다. 해당 변수를 통하여 db를 연결한다.
- Create the Tables
db를 저장하기 전에 먼저 db의 스키마를 만들어 주자. flaskr은 user table에 user 데이터를 저장해 두고, post table에 post를 저장해 둘 것이다. 아래와 같은 sql문을 통하여 스키마를 만들어 준다.
// flaskr/schema.sql
DROP TABLE IF EXISTS user;
DROP TABLE IF EXISTS post;
CREATE TABLE user (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password TEXT NOT NULL
);
CREATE TABLE post (
id INTEGER PRIMARY KEY AUTOINCREMENT,
author_id INTEGER NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
title TEXT NOT NULL,
body TEXT NOT NULL,
FOREIGN KEY (author_id) REFERENCES user (id)
);
그리고 위에서 만들어준 db.py에서, 위의 sql문을 읽어서 실행할 수 있도록 db.py의 close_db 함수 밑에 코드를 추가해주자.
def init_db():
db = get_db()
with current_app.open_resource('schema.sql') as f:
db.executescript(f.read().decode('utf8'))
@click.command('init-db')
def init_db_command():
"""Clear the existing data and create new tables."""
init_db()
click.echo('Initialized the database.')
이거 보면서, current_app 은 우리가 만든 flaskr 폴더 내부를 기본 route로 사용하는구나, 하고 느꼇다. 해당 폴더 안에 __init__.py 가 있고, 거기서 flask가 생성되어서 그런 걸까.
click.command('init-db') 는, terminal에서 flask 를 실행할 때 함수를 등록하는 것이라고 한다.
그러니까 저렇게 해 두면,
flask --app flaskr init-db
이라고 terminal에서 작성하면 바로 init_db_command를 호출할 수 있다는 말이란다.
- Register with the Application
위에서 만든 close_db / init_db_command를 등록해 주어야 한다. 여기에서는 __init__.py에서 app을 create할 때, db.py를 import 해 와서 app을 넘겨주고, 해당 app에다가 직접 함수들을 등록하는 방식을 취했다.
// flaskr/db.py
def init_app(app):
app.teardown_appcontext(close_db)
app.cli.add_command(init_db_command)
db.py에 위와 같은 코드를 추가해 주어, teardown 시 close_db 함수를 호출하게 해 주었고
cli에 init_db_command를 추가해 주었다.
// flaskr/__init__.py
import os
from flask import Flask
def create_app(test_config=None):
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping(
SECRET_KEY='dev',
DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),
)
~~~
from . import db
db.init_app(app)
~~~~
그리고 위와 같이, flask create_app 시에 db.init_app에 현재 app을 넘겨 주어서 정상적으로 db 초기화가 가능하게 만들었다!
그리고 init_db command를 쳐 보면!
이렇게 flaskr.sqlite가 만들어진다!
2023.07.18 - [Flask] - Flask 이용한 웹사이트 제작기 (4) - auth view code 작성
'Flask' 카테고리의 다른 글
Flask 이용한 웹사이트 제작기 (6) - static file 추가 (0) | 2023.07.22 |
---|---|
Flask 이용한 웹사이트 제작기 (5) - 기본 template 구현 (0) | 2023.07.21 |
Flask 이용한 웹사이트 제작기 (4) - auth view code 작성 (0) | 2023.07.18 |
Flask 이용한 웹사이트 제작기 (2) - 폴더 구조/ hello world 띄우기 (0) | 2023.07.15 |
Flask 이용한 웹사이트 제작기 (1) - 설치 (1) | 2023.07.10 |