FlaskはPythonで手軽にWebアプリケーションを開発できる軽量フレームワークです。SQLiteはインストール不要で使える軽量なデータベースです。これらを組み合わせれば、簡単なデータベースを使ったアプリを素早く構築できます。

本記事では、Python初心者の方に向けて、
- Flaskとは何か
- SQLiteを使った基本的なデータ保存方法
- SQLAlchemy(ORM)を使った実践的なDB連携
を 1本の記事で段階的に解説します。
この記事でできるようになること
Webアプリの全体像を理解しよう
まずは処理の流れをイメージします。
ブラウザ
↓
Flask(Python)
↓
データベース(SQLite)
↑
Flask
↑
ブラウザ
- ブラウザ:ユーザーが操作
- Flask:処理を担当
- DB:データを保存
この構造を理解できれば、Webアプリは一気に分かりやすくなります。
SQLiteの概要
SQLiteはファイルベースの軽量なDBMS(データベース管理システム)で、設定不要ですぐに使えます。サーバーを必要としないため、アプリケーションと一緒にそのまま配布できます。小規模なアプリケーションや学習用途、プロトタイピングに最適です。
Flaskとの接続は、SQLAlchemyというORM(Object Relational Mapper)を使うことで、より簡単になります。
- ファイル1つで使える
- サーバー不要
- Python標準で扱える
SQLiteは上記の特徴を持つ超軽量データベースです。
- 学習用アプリ
- 小規模Webアプリ
- Raspberry Pi などの組み込み用途
sqlite3でDB操作を理解する
sqlite3を用いたアプリ例になります。タスクアプリになります。
開発環境の準備
pip install flask
プロジェクト構成(sqlite3版)
flask_sqlite_app/
├── app.py
├── sample.db
└── templates/
└── index.html
SQLite(sqlite3)を使ったFlaskアプリ
データベース作成(初回のみ)
import sqlite3
conn = sqlite3.connect("sample.db")
cur = conn.cursor()
cur.execute("""
CREATE TABLE IF NOT EXISTS memo (
id INTEGER PRIMARY KEY AUTOINCREMENT,
text TEXT
)
""")
conn.commit()
conn.close()
DB生成のためのスクリプト。一回だけ実行。
Flaskアプリ本体(sqlite3版 app.py)
from flask import Flask, render_template, request, redirect
import sqlite3
app = Flask(__name__)
def get_db():
return sqlite3.connect("sample.db")
@app.route("/", methods=["GET", "POST"])
def index():
conn = get_db()
cur = conn.cursor()
if request.method == "POST":
text = request.form["text"]
cur.execute("INSERT INTO memo (text) VALUES (?)", (text,))
conn.commit()
cur.execute("SELECT * FROM memo")
rows = cur.fetchall()
conn.close()
return render_template("index.html", rows=rows)
if __name__ == "__main__":
app.run(debug=True)
ポイント解説
@app.route("/")
→ URLと処理を結びつけるrequest.form
→ HTMLフォームからの入力取得INSERT / SELECT
→ DBへの保存・取得render_template()
→ HTMLにデータを渡す
HTMLテンプレート(index.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Flask DB サンプル</title>
</head>
<body>
<h1>メモアプリ</h1>
<form method="post">
<input type="text" name="text">
<button type="submit">追加</button>
</form>
<ul>
{% for row in rows %}
<li>{{ row[1] }}</li>
{% endfor %}
</ul>
</body>
</html>
{% for %}:Pythonのfor文{{ }}:Python変数の表示
結果

sqlite3版のポイント
- SQL文を直接書く
- DBの構造が見えて理解しやすい
- 仕組みの学習に最適
sqlite3の注意点
- SQL文が増えると読みにくくなる
- SQLインジェクションのリスク
- DBを変更すると修正量が多い
👉 次のステップとしてORMを使う理由がここにあります。
SQLAlchemy(ORM)を使った実践構成
SQLAlchemyとは?
SQLAlchemy は PythonでDBを扱うためのライブラリで、ORM(Object Relational Mapper) と呼ばれる仕組みです。
SQL文を直接書かずに、安全で読みやすいコードが書けるのが特徴です。
主な機能:
- テーブル構造の定義
- データの追加・取得・更新・削除(CRUD)
- クエリのフィルタや並び替え
- リレーション(外部キー)によるテーブル結合も可能
ORMとは?
- Pythonのクラス = データベースのテーブル
- Pythonのオブジェクト操作 = DB操作
SQLを書かずにDBを扱えるのが最大の特徴です。
SQLAlchemyを使うメリット
| 項目 | sqlite3 | SQLAlchemy |
|---|---|---|
| SQL記述 | 必要 | 不要 |
| 可読性 | 低下しやすい | 高い |
| 安全性 | 自己管理 | 高い |
| 拡張性 | 低い | 非常に高い |
SQLAlchemyのインストール
Flask-SQLAlchemyという拡張ライブラリを使います。インストールは以下のコマンドで可能です:
pip install flask_sqlalchemy
プロジェクト構成(SQLAlchemy版)
flask_sqlalchemy_app/
├── app.py
├── app.db
└── templates/
└── index.html
Flask+SQLAlchemy アプリ(完成版)
from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///app.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
class Memo(db.Model):
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String(200), nullable=False)
@app.route("/", methods=["GET", "POST"])
def index():
if request.method == "POST":
memo = Memo(text=request.form["text"])
db.session.add(memo)
db.session.commit()
return redirect(url_for("index"))
memos = Memo.query.all()
return render_template("index.html", memos=memos)
if __name__ == "__main__":
with app.app_context():
db.create_all()
app.run(debug=True)
簡単な解説になります。
以下のようにFlaskアプリの設定ファイルにデータベースの場所(URI)を指定し、SQLAlchemyを初期化することで接続が完了します。
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///app.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
この設定により、同じディレクトリに「sample.db」という名前のSQLiteデータベースファイルが作成されます。
HTMLテンプレート
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Flask DB 入門</title>
</head>
<body>
<h1>メモアプリ</h1>
<form method="post">
<input type="text" name="text" required>
<button type="submit">追加</button>
</form>
<ul>
{% for memo in memos %}
<li>{{ memo.text }}</li>
{% endfor %}
</ul>
</body>
</html>
Flask × SQLAlchemyでCRUD操作を完全実装しよう
ここからは、これまで作成した メモアプリを拡張し、
CRUD(Create / Read / Update / Delete)操作をすべて実装します。
CRUDを理解すると、
- Webアプリの基本構造が分かる
- 実務レベルのアプリに一気に近づく
- 他のフレームワークにも応用できる
という大きなメリットがあります。
CRUDとは?(初心者向け)
CRUDとは、データベース操作の基本4つをまとめた言葉です。
| 操作 | 内容 | SQLAlchemyでの例 |
|---|---|---|
| Create | 作成 | db.session.add() |
| Read | 読み取り | query.all() |
| Update | 更新 | 値を書き換えて commit() |
| Delete | 削除 | db.session.delete() |
ほぼすべてのWebアプリは、このCRUDの組み合わせでできています。
完成後のアプリ動作
- メモを追加できる(Create)
- メモ一覧を表示できる(Read)
- メモを編集できる(Update)
- メモを削除できる(Delete)
プロジェクト構成(CRUD対応)
flask_sqlalchemy_crud/
├── app.py
├── app.db
└── templates/
├── index.html
└── edit.html
Flaskアプリ本体(CRUD完全版)
app.py(完成コード)
from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# DB設定
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///app.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
# ===== モデル =====
class Memo(db.Model):
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String(200), nullable=False)
def __repr__(self):
return f"<Memo id={self.id}>"
# ===== 一覧 & 追加(Read / Create)=====
@app.route("/", methods=["GET", "POST"])
def index():
if request.method == "POST":
text = request.form["text"]
memo = Memo(text=text)
db.session.add(memo)
db.session.commit()
return redirect(url_for("index"))
memos = Memo.query.order_by(Memo.id.desc()).all()
return render_template("index.html", memos=memos)
# ===== 編集(Update)=====
@app.route("/edit/<int:memo_id>", methods=["GET", "POST"])
def edit(memo_id):
memo = Memo.query.get_or_404(memo_id)
if request.method == "POST":
memo.text = request.form["text"]
db.session.commit()
return redirect(url_for("index"))
return render_template("edit.html", memo=memo)
# ===== 削除(Delete)=====
@app.route("/delete/<int:memo_id>", methods=["POST"])
def delete(memo_id):
memo = Memo.query.get_or_404(memo_id)
db.session.delete(memo)
db.session.commit()
return redirect(url_for("index"))
if __name__ == "__main__":
with app.app_context():
db.create_all()
app.run(debug=True)
コード解説(初心者向け)
Create(追加)
memo = Memo(text=text)
db.session.add(memo)
db.session.commit()
- Pythonオブジェクトを作成
- DBに登録
commit()で確定
Read(一覧取得)
memos = Memo.query.order_by(Memo.id.desc()).all()
SELECT * FROM memo- 新しいデータを上に表示
Update(更新)
memo.text = request.form["text"]
db.session.commit()
- データを取得
- 値を書き換え
commit()で反映
Delete(削除)
db.session.delete(memo)
db.session.commit()
- 削除対象を指定
- DBから完全に削除
HTMLテンプレート①(一覧画面)
templates/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Flask CRUD メモアプリ</title>
</head>
<body>
<h1>メモアプリ(CRUD対応)</h1>
<form method="post">
<input type="text" name="text" required>
<button type="submit">追加</button>
</form>
<ul>
{% for memo in memos %}
<li>
{{ memo.text }}
<a href="{{ url_for('edit', memo_id=memo.id) }}">編集</a>
<form action="{{ url_for('delete', memo_id=memo.id) }}"
method="post"
style="display:inline;">
<button type="submit">削除</button>
</form>
</li>
{% endfor %}
</ul>
</body>
</html>
HTMLテンプレート②(編集画面)
templates/edit.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>メモ編集</title>
</head>
<body>
<h1>メモ編集</h1>
<form method="post">
<input type="text" name="text" value="{{ memo.text }}" required>
<button type="submit">更新</button>
</form>
<p><a href="{{ url_for('index') }}">一覧に戻る</a></p>
</body>
</html>
結果

よくあるエラーと対処法
エラー1: RuntimeError: Working outside of application context.
原因: db.create_all() などをアプリケーションコンテキスト外で実行した。
対処法:
with app.app_context():
db.create_all()
エラー2: IntegrityError: UNIQUE constraint failed
原因: 一意性制約のあるカラム(例: email)に重複したデータを登録しようとした。
対処法: 登録前にデータの存在を確認するか、例外処理で対応する。
おわりに
SQLiteは小規模のアプリケーションに最適で、Flaskとの組み合わせは実用性が高いです。
次のステップでは、ユーザー登録やログイン機能の実装に進んでみましょう!
