データベース作成とか、なんだか本格的になってきました。
アプリっぽさがさらに増します。
flaskのチュートリアルでflaskrという小さなブログアプリの作成を進めています。今回は、データベースへのアクセスをするプログラミングです。色々とflask特有の概念が出現しましたので、まずは知識の整理から行いました。
行なっているチュートリアルはこちらです。
概念の整理
今回のデータベースへ接続を行う際に新しく覚えるべき概念がありましたので、そのあたりを整理していきたいと思います。
Flaskの特殊なオブジェクト
Flaskの「g」オブジェクト
「リクエスト毎にユニークなオブジェクト」とのことです。この段階では、1回のリクエストの間にグローバル変数のように扱えるオブジェクトがあると考えておくのが良さそうです。ここを深く考え始めると現段階の知識では沼にハマりそうです^^;
Flaskの「current_app」オブジェクト
「current_app」も同様に、深く考えると沼にハマりそうなので・・・flaskが実行しているアプリを示すようなオブジェクトと考えて進めていきます。
こういうflaskで準備された特殊なオブジェクトがあるんですね。
あるんです!
SQLite
データベースサーバーを準備したりすることなく、アプリケーションに組み込んで利用できるようなデータベースです。チュートリアルでは、簡単に扱うことのできるSQLiteをデータベースとして接続するような例となっています。
SQLiteのデータベースは単一のファイルとして保存されますので、バックアップが簡単などの利点があるらしいです。
ズバリ、簡単に利用できるデータベース!
Flaskのカスタムコマンド
チュートリアルで、コマンドライン上で実行するFlaskコマンドを定義しています。いつも、「flask run」としてデバッグ用のWebサーバーを立ち上げていますが、このような「flask + ●●」というflaskコマンドを自分で作成できるような機能です。
今回のチュートリアルでは、アプリがデータベースを利用します。アプリの初回起動時にはデータベースが存在していないので、あらかじめ空のデータベーステーブルを作成するために「init-db」というコマンドを作成するために利用しています。
Flaskのカスタムコマンドの詳細については、次のページでも解説されいます。
チュートリアルのプログラミング
データベース用のプログラムを作成します。flaskrフォルダの中に「db.py」という名前のPythonプログラムを作成します。
チュートリアルとは趣向を変えて、プログラムファイル毎にまとめたいと思います。
#SQLiteというデータベースを利用するためimport
import sqlite3
#flaskのカスタムコマンドを利用するためclickをimport
import click
from flask import current_app, g
from flask.cli import with_appcontext
#①「g」にデータベース(以下DB)コネクションを確立する関数
def get_db():
#同じリクエストでgにDBコネクションがない場合connect
if 'db' not in g:
#SQLite3のconnectメソッドで指定のDBへ接続
g.db = sqlite3.connect(
#実行中のFlaskアプリの「DATABASE」を見る。__init__.pyで設定したやつです。
current_app.config['DATABASE'],
detect_types=sqlite3.PARSE_DECLTYPES
)
#DBをカラム名で取得できるようにする
g.db.row_factory = sqlite3.Row
#gにdbを返す
return g.db
#②DBを閉じる処理
def close_db(e=None):
db = g.pop('db', None)
if db is not None:
db.close()
#③DBを初期化する処理
def init_db():
db = get_db()
with current_app.open_resource('schema.sql') as f:
db.executescript(f.read().decode('utf8'))
#④Flaskのカスタムコマンドとしてinit-dbを登録する
@click.command('init-db')
@with_appcontext
def init_db_command():
"""Clear the existing data and create new tables."""
init_db()
click.echo('Initialized the database.')
#⑤アプリに登録
def init_app(app):
app.teardown_appcontext(close_db)
app.cli.add_command(init_db_command)
「db.py」では以下の機能を実装しています。
①DBコネクションを確率する関数
データベースファイルへ接続する処理を行います。データベースはまずコネクションを確立(接続を行う手順の実行)しなければいけないです。
②DBを閉じる関数
データベースを安全に閉じます。
③DBを初期化する関数
後述する、カスタムコマンドでデータベースを初期化(主キーやどんな項目のデータがあるかなどを定義してからのデータベースを作成)する処理の実態です。
この関数で呼び出しているのは、「schema.sql」というSQLのスクリプトで、SQLを実行してデータベースを初期化します。
④Flaskのカスタムコマンドを作成
データベースの初期化については、Webアプリを初めて立ち上げる前にあらかじめ空のデータベースを作成して、「どんなデータを管理するか」を定義しておく必要があるため、Webアプリを立ち上げる前にflaskコマンドにてデータテーブルの定義などを行います。
⑤アプリに登録
init_appという関数を定義して、アプリのインスタンスに、「close_db」と、「init_db_command」を設定します。init_app関数自体は、__init__.pyのアプリケーションファクトリ内に記載されます。
今回のまとめ
データベースの項目が途中となっていますが、今回は、データベース接続を行うための概念の整理と、データベースへ接続するためのPythonプログラムを作成するところまでとします。次回は、データベースの定義を行うところから(schema.sqlの作成)進めていきたいと思います。