【Python】Flask入門 Flask-SQLAlchemyの使い方

Flask

はじめに

PythonのWEBフレームワークであるFlaskの拡張機能である、Flask-SQLAlchemyについて解説します。

しげっち
しげっち

Flask環境向けにSQLAlchemyを簡易的に利用可能にする拡張機能だよ。

にゃーすけ
にゃーすけ

これを覚えればFlaskの環境でSQL文を気にすること無く、データのやり取りができるようになるにゃ。

通常のSQLAlchemyについては下記で解説しています。

Flask学習におすすめの本を紹介します。
⇨【Python】Flask入門におすすめの本 3選

Flask-SQLAlchemyのインストール

まずはインストールを行います。

pip instal Flask-SQLAlchemy

Flask-SQLAlchemyの環境準備

今回の説明に用いる環境は下記とします。

  • Python 3.7.0
  • Flask 2.0.2
  • Flask-SQLAlchemy 2.5.1

Flask-SQLAlchemyのバージョンによっては処理の途中でエラーとなってしまう場合があります。
私はエラーの特定にかなりハマってしまいました。
エラーの詳細は後ほど記載しますが、ひとまず2.5.1のバージョンであれば正常に動作することを確認しています。

Flask-SQLAlchemyを使用してみよう

しげっち
しげっち

環境の準備ができたらサンプルを見ていきましょう!

作成するサンプルについて

下記画像の様に商品名と値段を入力して、一覧に追加するアプリを作成していきます。

インポートの記載とconfigの設定

にゃーすけ
にゃーすけ

まずは、app.pyから書いていくにゃ

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

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']= 'sqlite:///Test.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_ECHO']=True

インポートにはflaskflask-sqlalchemyをそれぞれ記載します。
configには3つ記載しました。

SQLALCHEMY_DATABASE_URIはデータベースの接続先を記載します。今回はSQLiteを使用します。

SQLALCHEMY_TRACK_MODIFICATIONSはFALSEにします。
公式サイトには下記のように記載がありました。

If set to True, Flask-SQLAlchemy will track modifications of objects and emit signals. The default is None, which enables tracking but issues a warning that it will be disabled by default in the future. This requires extra memory and should be disabled if not needed.

Flask_SqlAlchemy公式サイト

Trueにしておくと、メモリを消費するようなことが書いてあるのでFalseにしておくのが良いと思います。

SQLALCHEMY_ECHOをTrueにするとSQL文等のログを出力してくれます。
VSCodeの場合はターミナル内にログが表示されました。

クラスの定義とデータベースの作成

config設定後の続きになります。

db = SQLAlchemy(app)

class Shohin(db.Model):
    __tablename__ = 'Shohin'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Text)
    price = db.Column(db.Integer)


@app.before_first_request
def init():
    db.create_all()

ここではShohinという名前でクラスを作成します。
ここで作成したクラスの構成がそのままデータベースにテーブルとして反映されます。

@app.before_first_requestのデコレータは最初のrequestの時だけデコレートしている関数を実行します。
db.create_all()を実行したら、クラスの内容に基づき、テーブルが作成されます。
SQLiteの場合、ファイル(今回の場合Test.db)が無ければファイルの作成も行ってくれるので、予め準備しておく必要はありません。

上記画像ですが、SQLiteのデータをGUIで参照・編集できるアプリケーションで確認しています。アプリケーションの詳細は下記のページを参照ください。

db.create_all()でハマったこと

db.create_all()の処理でエラーとなってしまう現象にハマってしまいました。
原因はFlask-SQLAlchemyの特定バージョンで発生するバグだったようです。

当初使用していたFlask-SQLAlchemyのバージョンは2.3.2を使用していましたが、このバージョンだとエラーになってしまいます。
公式サイトのサンプルソースをそのまま実行してもエラーになってしまい、何が悪いのかさっぱりわからず諦めかけていたのですが、
試しに最新のバージョン(現時点で2.5.1)にするとエラーが起きなくなりました。


GET・POSTの処理

しげっち
しげっち

これでapp.pyのソース内容は最後です。

@app.route('/', methods=['GET'])
def index():
    datas = Shohin.query.all()
    return render_template('index.html', lists = datas)

@app.route('/result', methods=['POST'])
def insert():
    name_txt = request.form['name']
    price_txt = request.form['price']
    shohin = Shohin(name = name_txt, price = price_txt)

    db.session.add(shohin)
    db.session.commit()

    return redirect('/')

if __name__ == '__main__':
    app.debug = True
    app.run(host='localhost')

GET送信で実行されるindex関数では、Shohin.query.all()でデータベースから登録済みの商品一覧の内容をすべて取得しています。
最初に説明したSQLALCHEMY_ECHOをTrueにしていればSELECT文が実行されたログが表示されます。

取得したデータはテンプレートに渡しています。

POST送信ではテンプレートから商品名と値段を取得し、それを基にshohinオブジェクトを作成し、db.session.addしています。
db.session.commit()でデータベースに登録を行います。
最後にredirect(‘/’)してindex関数を実行させ、追加した商品を含めて全データを読み込み、テンプレートに渡しています。

if name == ‘main‘:以下はお決まりの記載ですが、ターミナルでサーバー実行処理しなくても、app.pyを実行すればサーバーを実行してくれます。

テンプレートの内容

にゃーすけ
にゃーすけ

次はテンプレートであるindex.htmlの内容について見て行くにゃ!

<!DOCTYPE html>
<html lang="jp">
<head>
    <meta charset="UTF-8">
    <title>商品一覧</title>
</head>
<body>
    <div>
        <table>
            <thead>
                <tr>
                    <th>ID</th>
                    <th>商品名</th>
                    <th>値段</th>
                </tr>
            </thead>
            <tbody>
                {% for item in lists %}
                <tr>
                    <th>{{item.id}}</th>
                    <th>{{item.name}}</th>
                    <th>{{item.price}}</th>
                </tr>
                {% endfor %}
            </tbody>
        </table>
    </div>    
    <form action='/result'>
        <p><新規登録></p>
        <label>
            商品名    
            <input type="text" name="name">
        </label>
        <label >
            値段
            <input type="text" name="price">       
        </label>
        <button type="submit" formmethod="POST">登録</button>
    </form>
    
</body>
</html>

app.pyから渡されたデータは、listsの変数に入っています。
{% for item in lists %}でデータの中身を繰り返し取得しtableの形式で表示しています。

form action以下は新規に商品名と値段を入力して登録できるようにしています。

にゃーすけ
にゃーすけ

これで完成だにゃ!


まとめ

Flask-SQLAlchemyの使用方法について解説しました。

しげっち
しげっち

今回のサンプルでは既存編集や削除は行なっていないので、ぜひ処理を追加してみてほしいな!

にゃーすけ
にゃーすけ

頑張って追加してみるにゃ!

しげっち
しげっち

最後まで読んでいただき、ありがとうございます!

Flask学習におすすめの本を紹介します。
⇨【Python】Flask入門におすすめの本 3選

Flask入門まとめページ

タイトルとURLをコピーしました