Flask学習|Flask-SQLAlchemyでデータベース操作を完全習得【チャプター5-07】

一つ前のページではrelationshipについて学習しました。
今回は Flask-SQLAlchemy について見ていきましょう。
Chapter1:Flask入門編
Chapter2:Jinja2入門編
Chapter3:フィルター編
Chapter4:フォーム編
Chapter5:データベース編
・Chapter5-1:データベースとは何か
・Chapter5-2:データベースを作ろう
・Chapter5-3:データベースを操作しよう
・Chapter5-4:SQLAlchemyを使おう
・Chapter5-5:内部結合と外部結合を理解しよう
・Chapter5-6:relationshipを理解しよう
・Chapter5-7:Flask-SQLAlchemyを使おう ◁今回はここ
・Chapter5-8:Flask-Migrateを使おう
Chapter6:エラーハンドリングとデバッグ編
Chapter7:アプリ開発編
Flaskを使ってWebアプリケーションを開発する際、ユーザー情報や投稿内容などのデータを保存・管理するために、データベースとの連携が欠かせません。
この連携を手軽に実現してくれるのが、Flask専用の拡張ライブラリ Flask-SQLAlchemy です。
Flask-SQLAlchemyは、PythonのORMライブラリ「SQLAlchemy」とFlaskをつなぐ架け橋となり、複雑なSQL文を書かずに Pythonのクラスを使ってデータベースを操作 できるようにしてくれます。
このページでは、Flask-SQLAlchemyの基本的な導入から、モデルの定義、データの登録・取得・更新・削除といった操作方法までを、具体的なコードと一緒に学びます。
- Flask-SQLAlchemyとは何か?
- Flask-SQLAlchemyのインストールと初期設定
- モデルの作成とデータベースとの接続方法
- データの追加、取得、更新、削除の操作方法
本記事は 有料記事(100円)ですが、現在は期間限定で無料公開中です。
Flask-SQLAlchemyとは?初心者向けに仕組みとメリットを解説
Flask-SQLAlchemy は、Pythonの代表的なORMライブラリ「SQLAlchemy」を、Flaskで簡単に使えるようにするためのFlask拡張です。
もともとSQLAlchemyは非常に高機能ですが、そのままではFlaskとの連携に手間がかかります。
Flask-SQLAlchemyを使うことで、Flaskアプリに自然な形でSQLAlchemyを統合し、シンプルな記述でデータベース操作が可能になります。
また、SQL文を書く必要がなく、Pythonのクラスとメソッドでデータベースの定義や操作ができるため、初心者にも扱いやすいのが特長です。
インストールと初期設定|環境構築の基本ステップ
まずはFlask-SQLAlchemyをインストールして、Flaskアプリに組み込むための準備をしましょう。
以下のコマンドを使って、Flask-SQLAlchemyをインストールします。
pip install Flask-SQLAlchemy
仮想環境を使っている場合は、仮想環境を有効化した状態でこのコマンドを実行してください。
コードで学ぶFlask-SQLAlchemyの使い方|CRUDの流れを完全マスター
この章では、実際のコードを使ってFlask-SQLAlchemyをどのように活用していくのかを一つひとつ確認していきます。
コードの上から順に紹介しますので、これまでの記事と同様にコピーしてVSCodeに貼り付けていきながら読んでください。
FlaskとSQLAlchemyの読み込み方法
まずは必要なライブラリを読み込み、Flaskアプリケーションの本体を初期化します。
import os # 標準ライブラリ「os」をインポート from flask import Flask # Flaskをインポート from flask_sqlalchemy import SQLAlchemy # SQLAlchemy:DBとPythonクラスを紐づけるライブラリ app = Flask(__name__) # Flaskアプリケーションのインスタンス生成
os
:ファイルパスを扱うための標準ライブラリ。後にデータベースファイルの場所を動的に取得するために使います。Flask
:Webアプリの枠組みを提供するフレームワーク。SQLAlchemy
:ORM(オブジェクト関係マッピング)ライブラリ。Pythonクラスでテーブル操作を可能にします。app = Flask(__name__)
:Flaskアプリケーションのインスタンスを作成します。__name__
によりFlaskがテンプレートや静的ファイルの場所を判断できます。
データベース接続設定の基本
アプリケーションにセキュリティ設定とデータベース接続設定を追加します。
# ------ Flaskに関する設定 ------ # セッション保護用のランダムな秘密鍵を設定 app.config['SECRET_KEY'] = os.urandom(24) #24バイトのランダムバイト列を作成し、SECRET_KEYというキー名で辞書に追加 # DBファイルの設定 base_dir = os.path.dirname(__file__) # 現在のPythonファイルがあるディレクトリの絶対パスを取得 database = 'sqlite:///' + os.path.join(base_dir, 'data.sqlite') # base_dir内のdata.sqliteというファイルへのパスを作成し、 # SQLite用の接続文字列(URL形式)を追加して変数databaseに代入 app.config['SQLALCHEMY_DATABASE_URI'] = database # DBのURLをSQLALCHEMY_DATABASE_URIというキー名で辞書に追加 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # SQLAlchemyの「変更追跡機能」を無効化にしてメモリ使用を軽減 # db変数を使用してSQLAlchemyを操作 db = SQLAlchemy(app) # SQLAlchemyオブジェクトをインスタンス生成して変数dbへ代入 # このdbを使って「モデル定義」や「データベースへの登録・更新・削除」などの操作ができるようになる
SECRET_KEY
:CSRF対策などに使われる秘密鍵をランダムに生成。セッションの保護に必要です。SQLALCHEMY_TRACK_MODIFICATIONS
: モデル変更の検出機能をオフにし、パフォーマンスとメモリ使用量を最適化。db = SQLAlchemy(app)
:この1行でFlaskアプリとSQLAlchemyの連携が確立され、モデルやクエリ操作が可能になります。
モデルクラスの作成とテーブル定義
読み終えた本の情報を保存する「BookLog」モデルを定義します。
# 読み終わった本テーブル class BookLog(db.Model): # db.Modelクラスを継承したBookLogクラスの定義 # テーブル名 __tablename__ = 'book_logs' # 対応するテーブル名を明示 # 書籍ID id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 書籍のタイトル title = db.Column(db.String(200), nullable=False) # 表示用関数 def __str__(self): return f"書籍ID:{self.id} タイトル:{self.title}"
BookLog
: データベースの1テーブルを表現するPythonクラス。__tablename__
: SQL上のテーブル名を明示的に設定(省略時はクラス名を小文字化)。id
: 主キー(自動増分の整数)。書籍を一意に識別するためのID。title
: 書籍のタイトル。文字列200文字まで、必須項目(nullable=False)。__str__
: このメソッドを定義することで、インスタンスをprint()
したときに分かりやすく表示される。
Flask-SQLAlchemyでは、モデルクラスを定義することでテーブル構造をそのままPythonのコードで表現できます。
このテーブルの作り方は、FlaskでSQLAlchemy入門|ORMで直感的にデータベース操作する方法 の記事で詳しく解説しています。
DBの初期化と初期データ登録
次に、テーブルの作成と初期データの登録を行う関数を定義します。
# ------ DB作成 ------ def init_db(): # DBを作成するinit_db()関数を定義 with app.app_context(): # Flaskの「アプリケーションコンテキスト」を有効化 # これにより「db.session」を使った操作が可能になる print('テーブルを削除してから作成') db.drop_all() # 既存のテーブルを全て削除(初期化) db.create_all() # モデル(BookLog)に基づいてテーブルを作成 # データ作成 print("データ登録:実行") book_log01 = BookLog(title='ノルウェイの森') # BookLogクラス(モデル)をインスタンス生成し、book_log01に代入 book_log02 = BookLog(title='1Q84') # 同上 book_log03 = BookLog(title='容疑者Xの献身') # 同上 db.session.add_all([book_log01, book_log02, book_log03]) # まとめて登録 db.session.commit() # データベースに保存
init_db()
:データベース初期化を行う関数。主に開発時のリセット用途です。app.app_context()
:Flaskアプリケーションの実行コンテキストを有効化。これがないとDB操作ができません。db.drop_all()
:すべての既存テーブルを削除。db.create_all()
:定義したモデル(ここではBookLog
)を元に新たなテーブルを作成。add_all(...)
:複数のBookLogインスタンスを一括で登録。db.session.commit()
:セッション内容をデータベースに反映して保存。
この関数を実行することで、テーブルの作成+サンプルデータの挿入が一度に行えます。
セッションが何かが分からない人は、↓↓の記事を参考にしましょう。
データ登録処理の実装
ここでは、新しい本のデータを1件データベースに追加します。
# ------ テーブル操作(CRUD操作) ------ # 登録 def insert(): # データを登録するinsert()関数を定義 print('1件登録') with app.app_context(): # Flaskの「アプリケーションコンテキスト」を有効化 book_log04 = BookLog(title='博士の愛した数式') # BookLogクラスをインスタンス生成し、book_log04に代入 # 「title='博士の愛した数式'」はPythonのキーワード引数 db.session.add(book_log04) # book_log04をセッションに追加 db.session.commit() # セッションをデータベースに反映(保存) print('登録 ->', book_log04)
BookLog
モデルを使って新しい本のデータを作成。db.session.add()
で登録を予約し、commit()
で保存確定。app.app_context()
によってFlaskアプリの文脈を有効にし、DB操作を可能にします。- 最後に登録されたインスタンスを出力。
データ一覧を取得する方法
ここでは、保存されているすべての本のデータを一覧で取得します。
# 全件参照 def select_all(): # データを全件参照するselect_all()関数を定義 print('全件取得') with app.app_context(): book_logs = BookLog.query.all() # BookLogクラスのquery属性のall()メソッドで全データを取得し、変数book_logsに代入 for book_log in book_logs: print (book_log)
BookLog.query.all()
により全データをリストとして取得。for
文でループし、各インスタンスを表示。
主キーで1件だけ取得する方法
ここでは、主キー(ID)を使って特定の1件のデータを取得します。
# 1件参照 def select_filter_pk(pk): # データを1件参照するselect_filter_pk()関数を定義 print('1件取得') with app.app_context(): target = BookLog.query.filter_by(id = pk).first() # BookLog.queryでクエリを開始し、filter_by(id=pk)でIDが一致するものを絞り込み # .first()で最初の1件だけ取得してtargetに代入(該当なしならNoneになる) print('取得結果 ->', target)
filter_by(id=pk)
で条件検索し、first()
で最初の1件を取得。- 結果は
None
の可能性もあるため、実際のアプリでは存在チェックが必要です。 - ここでは取得できた本の情報をそのまま出力しています。
データの更新処理を実装する
ここでは、指定されたIDの本のタイトルを更新します。
# 更新 def update(pk): # データを更新するupdate()関数を定義 print('更新実行') with app.app_context(): target = BookLog.query.filter_by(id = pk).first() # query属性で検索条件を指定し、idがpkと一致する最初の1件を取得してtargetに代入 print('更新前 ->', target) target.title = 'タイトルを変更' db.session.add(target) # targetをセッションに追加 db.session.commit() # セッションをデータベースに反映(保存)
- 指定されたIDの本を検索し、
title
を新しい文字列に変更。 add()
を使ってセッションに登録し、commit()
で確定。- 登録済みオブジェクトの更新も、SQLAlchemyではこのように簡潔に記述できます。
指定IDのデータを削除する
ここでは、IDを指定してデータベースから本のデータを削除します。
# 削除 def delete(pk): # データを削除するdelete()関数を定義 print('削除処理') with app.app_context(): target = BookLog.query.filter_by(id = pk).first() # query属性で検索条件を指定し、idがpkと一致する最初の1件を取得してtargetに代入 db.session.delete(target) # targetをセッションから削除 db.session.commit() # セッションをデータベースに反映(保存) print('削除 ->', target)
- 指定IDで検索したデータを削除対象として
session.delete()
に渡します。 commit()
によって、DB上から実際に削除されます。- 削除されたインスタンスは表示上では残っていますが、次回取得時には存在しません。
一連処理をまとめて実行する
ここでは、初期化・登録・更新・取得・削除・全件取得の一連の処理を順番に実行します。
# ------ 実行 ------ if __name__ == '__main__': init_db() insert() update(1) select_filter_pk(1) delete(2) select_all()
__name__ == '__main__'
は、このファイルが直接実行されたときのみ以下を実行するというPythonの慣習です。
これにより、次の操作を順に実行されます。
- テーブルの初期化と初期データ登録
- 新しい書籍の追加
- 書籍ID1番のタイトル更新
- 書籍ID1番のデータ取得
- 書籍ID2番の削除
- 全データ一覧の表示
まとめ|Flask-SQLAlchemyの実践力を習得しよう
Flask-SQLAlchemyは、Flaskアプリケーションにデータベース機能を組み込む際に非常に有効な拡張機能です。
この記事では、その基本的な使い方を通じて、以下のポイントを学びました。
- Flask-SQLAlchemyの役割と導入方法
- モデルクラスを用いたテーブル定義の基本
- 初期データの登録を含む、データベースの初期化処理
- データの登録・取得・更新・削除といった基本的な操作(CRUD)
各操作はFlaskのアプリケーションコンテキスト内で行う必要があること、そしてSQLAlchemyが提供する直感的なAPIにより、SQLを直接書かずに高度な操作が可能であることを確認できたと思います。
データベースとやりとりする仕組みをアプリに組み込むことで、Flaskアプリは一気に実用的なツールへと進化します。
ぜひ、今回学んだコードをベースに、独自のモデルや操作関数を試してみてください。
FAQ|Flask-SQLAlchemyの実践操作でよくある質問
- Q1. Flask-SQLAlchemyのセッションは毎回作成する必要がありますか?
-
いいえ、基本的にアプリ全体で1つのセッションオブジェクトを使いまわす設計です。ただし、アプリケーションの規模やスレッドの使い方によってはセッションスコープの管理が重要になります。
- Q2. db.session.commit()を忘れるとどうなりますか?
-
commit()を忘れると、追加・更新・削除したデータはデータベースに反映されません。一見エラーが出なくても保存されていない状態なので注意が必要です。
- Q3. with app.app_context(): はなぜ必要なのですか?
-
Flaskアプリの外でデータベース操作を行う際、Flaskはどのアプリケーションの文脈かを判断できません。
app.app_context()
を使うことで、Flaskに現在のアプリケーション情報を明示し、DB操作を可能にします。