コンテンツにスキップ

5 データベースとの連携

5.1 データベースの基本

データベースを利用するWebサイトを作ります。

今回はSQLiteというpythonにあらかじめ付属するデータベースを使います。VisualStudio CodeにSQLiteのファイルを扱う拡張機能「SQLite3 Editor」をインストールしておきます。コマンドラインで以下から可能です。

code --install-extension yy0931.vscode-sqlite3-editor

もしくはVisualStudio Code画面左の拡張機能のボタンを押して、「SQLite3 Editor」と入力します。

hanbai.py に記述していきます。 まず、これまでと同様に変数appにFlaskオブジェクトを作成します。

from flask import Flask, render_template, request, redirect
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime

app = Flask(__name__)

次にデータベースを扱う準備をします。ファイル名を指定し、データベースを扱うライブラリ SQLAlchemy のオブジェクト db を作成します。今回は商品や売り上げを管理する販売管理をテーマにし、hanbai.dbというファイルにします。

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///hanbai.db'
db = SQLAlchemy(app)

5.2 モデルの生成

今回は商品を管理する以下のようなテーブルを作成します。

shouhinテーブル

  • 商品ID sid (整数:Integer) 主キー
  • 商品名 sname (文字列:String 最大255文字)
  • 単価 tanka (整数:Integer)

そのために、商品テーブルのデータを一件入れるためのクラス、Shouhinを作成します。これはSQLAlchemyの「モデル」の作り方に従い作成します。「モデル」とはテーブルの一件のデータを入れる入れ物です。列名を以下のように指定します。

class Shouhin(db.Model):
    sid = db.Column(db.Integer, primary_key=True)
    sname = db.Column(db.String(255))
    tanka = db.Column(db.Integer)

db.Integerで整数型、db.Stringで文字列型になります。Stringの場合、最大文字数を指定します。また、sidは主キーなので primary_key=True も付加します。

まず、テーブルを作成します。これはdb.create_all() で可能です。 起動時にこれを実行するようにwith app.app_context()の配下に書きます。

with app.app_context():
    db.create_all() # テーブル作成

実行すると、 instanceフォルダにhanbai.dbというファイルが作成されます。これを開くとshouhinテーブルがあるはずです。

問題

売上テーブルを作成しよう。クラス名はUriageとする。以下の列を作成する、

  • 売上ID uid (整数:Integer) 主キー
  • 商品ID sid (整数:Integer)
  • 販売個数 kosu (整数:Integer)
  • 販売日付 hi (日付:Date)※初期値は今日 default=date.today

5.3 初期データ設定

次に、初期データを設定します。これもwith app.app_context()配下に書きます。

    # 初期データ追加
    if Shouhin.query.count() == 0:
        data = [
            Shouhin(sname="りんご", tanka=100),
            Shouhin(sname="みかん", tanka=150),
            Shouhin(sname="いちご", tanka=120),
        ]
        db.session.add_all(data)
        db.session.commit()

データがテーブルに存在しないかを確認します。これはShouhin.query.count() でデータの個数を確認します。データが存在しないようなら、初期データをリスト data に入れます。データはShouhinクラスのインスタンスとして生成します。

Shouhinクラスにはsid、sname、tankaの3つの属性がありますが、snameとtankaのみを指定します。sidは主キーのため、自動で生成されるからです。

その後、db.session.add_all(リスト)でリストの内容が全て追加されます。 ただし、db.session.commit() をその後にしないとこの結果が確定されません。データベースを更新(追加、変更、削除)した際にはこれが必要になることを覚えておきましょう。

実行すると、instanceフォルダのhanbai.dbにデータが入っています。

問題

uriageテーブル にも以下のようなデータを初期データとして追加する。

  • 一件目 sid:1 kosu:5
  • 二件目 sid:2 kosu:3
  • 三件目 sid:3 kosu:1
  • 四件目 sid:1 kosu:2

data配列にShouhinと同様に追加せよ。

5.4 全検索

次に全検索を行うトップページを作成します。今回のhanbai.pyで扱うテンプレートは templates 配下のhanbaiフォルダ内に入れていきます。

トップページは商品一覧を表示します、商品テーブルを全検索し、それをhanbai/slist.htmlで表示します。Shouhin.query.all() でshouhinテーブルの全ての行を取得します。取得した rows を slist.htmlに渡します。

@app.get('/')
def index():
    rows = Shouhin.query.all() # 全検索
    return render_template('hanbai/slist.html',rows=rows)

テンプレート hanbai/slist.htmlでは表形式で全てをfor文で表示します。rowsから一行文を r に取り出しています。 r から r.列名 で参照できます。

<table>
    <tr><th>商品ID</th><th>商品名</th><th>単価</th></tr>
    {% for r in rows %}
    <tr>
    <td>{{r.sid}}</td>
    <td>{{r.sname}}</td>
    <td>{{r.tanka}}</td>
    </tr>
    {% endfor %}
</table>

問題

/ulist でアクセスすると uriageテーブルの内容を全て表示する。ulist関数を作成しよう。テンプレートは ulist.html を使用する。