FlaskのSQLAlchemyでリレーション(外部キー)を設定する方法を初心者向けに解説!
生徒
「Flaskでデータベースの中に関係を作りたいんですが、どうすればいいですか?」
先生
「Flaskでは、SQLAlchemyという仕組みを使って、外部キーという“つながり”を作ることができますよ」
生徒
「外部キーってなんですか?難しそうでよくわかりません……」
先生
「心配いりません。リレーション(関係)という考え方を、わかりやすく説明していきましょう!」
1. リレーション(外部キー)とは?
リレーションとは、2つのテーブル(表)を“つなげる”仕組みのことです。
例えば、「生徒の情報」と「クラスの情報」があるとします。どの生徒がどのクラスに所属しているか、という関係を表すには、外部キー(がいぶきー)という“つながりの線”を使います。
もっと身近な例で言うと、「お弁当注文表」と「お弁当メニュー表」です。注文表には「メニューID」が書かれていて、それがメニュー表の「ID」と一致すれば、何を頼んだかがわかる、という仕組みです。
2. SQLAlchemy(エスキューエル・アルケミー)とは?
SQLAlchemyは、Pythonでデータベースを使うための道具です。Flaskと一緒に使うことで、難しいSQL(エスキューエル)文を書かなくても、Pythonのコードだけでデータベースを操作できます。
SQLAlchemyは、ORM(オーアールエム)という仕組みで動いています。ORMとは、「オブジェクトとデータベースを自動でつなげるしくみ」のことです。
3. 外部キーのあるモデルを作ってみよう
それでは、FlaskとSQLAlchemyを使って、「生徒(Student)」と「クラス(Classroom)」の関係を表すモデルを作ってみましょう。
生徒は1人1つのクラスに所属し、クラスは複数の生徒を持ちます。これを「1対多(いちたいた)」のリレーションといいます。
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Classroom(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False)
students = db.relationship("Student", backref="classroom", lazy=True)
class Student(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False)
classroom_id = db.Column(db.Integer, db.ForeignKey("classroom.id"), nullable=False)
ここがポイント!
db.ForeignKey("classroom.id")は「どのクラスに所属しているか」を示します。db.relationship("Student", backref="classroom")は「このクラスに属している生徒一覧」を取り出せるようにします。- backref とは、「生徒側からクラスを見られるようにする」しくみです。
4. データを追加してみよう
クラスと生徒を実際に登録してみます。
# クラスを1つ作成
class1 = Classroom(name="1年A組")
db.session.add(class1)
db.session.commit()
# 生徒を2人登録して、このクラスに所属させる
student1 = Student(name="山田太郎", classroom_id=class1.id)
student2 = Student(name="佐藤花子", classroom_id=class1.id)
db.session.add(student1)
db.session.add(student2)
db.session.commit()
5. データを読み取ってみよう
リレーション(関係)を使って、クラスから生徒を取り出したり、生徒からクラスを取り出したりできます。
# クラスに所属する生徒を取り出す
class1 = Classroom.query.first()
for student in class1.students:
print(student.name)
# 生徒が所属しているクラス名を取り出す
student = Student.query.first()
print(student.classroom.name)
山田太郎
佐藤花子
1年A組
6. テーブルの設計図がどうつながっているかを図でイメージしよう
このリレーションのイメージを簡単に図で表すと、次のようになります:
Classroom テーブル
+----+-------------+
| id | name |
+----+-------------+
| 1 | 1年A組 |
+----+-------------+
Student テーブル
+----+------------+--------------+
| id | name | classroom_id |
+----+------------+--------------+
| 1 | 山田太郎 | 1 |
| 2 | 佐藤花子 | 1 |
+----+------------+--------------+
classroom_idが、クラスのidと一致して、つながっているのが外部キーです。
7. よくあるエラーとその対処法
FlaskとSQLAlchemyでリレーションを使うときに、初心者がよくつまずくポイントをまとめました。
- ForeignKeyのスペルミス:「classroom.id」と書くべきところを「classroomID」などにするとエラーになります。
- db.relationshipを忘れる:関係を双方向にしたい場合は、
relationshipを忘れないようにしましょう。 - マイグレーションをしていない:モデルを変更したら、必ずデータベースに反映(マイグレーション)しましょう。
8. HTMLフォームで登録・表示するには?
Flaskでは、HTMLのフォームからクラスと生徒のデータを送信することもできます。ここでは簡単なフォームの例を紹介します。
<form action="/add_student" method="post">
生徒名:<input type="text" name="name"><br>
クラスID:<input type="number" name="classroom_id"><br>
<input type="submit" value="登録">
</form>
このフォームで生徒の名前とクラスIDを入力して、「登録」ボタンを押すと、生徒が追加されます。
9. Flaskのルーティングで処理を作る
フォームの送信先(/add_student)をFlaskで受け取るコードも書いておきましょう。
from flask import Flask, request
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///school.db"
db.init_app(app)
@app.route("/add_student", methods=["POST"])
def add_student():
name = request.form.get("name")
classroom_id = request.form.get("classroom_id")
student = Student(name=name, classroom_id=classroom_id)
db.session.add(student)
db.session.commit()
return "生徒を追加しました!"
このコードで、フォームから送られてきた情報を使って、生徒のデータを保存します。
まとめ
リレーションの理解を深める総まとめ
FlaskのSQLAlchemyで扱うリレーションは、初心者にとって最初は少しむずかしく感じられる部分ですが、実際には日常生活の中の仕組みにとても近い考え方で動いています。生徒とクラスの関係、お弁当の注文票とメニュー表、会員と注文履歴など、身近な関係性を整理するようにデータを構造化するのがリレーションの基本です。特に外部キーという仕組みは、情報同士のつながりを正しく結びつけるための重要な軸になり、データの整合性を守るためにも欠かせない存在です。 FlaskとSQLAlchemyを組み合わせることで、複雑なデータベース構造もPythonのコードだけで自然に書けるようになり、アプリケーション全体の整理もしやすくなります。外部キーやリレーションを理解していくと、アプリがどのようにデータを結びつけて動いているのかがよく見えるようになり、Webアプリケーション開発の全体像がさらに楽しく感じられるはずです。 この記事では、生徒とクラスを例に「一対多」の関係を中心に説明しましたが、実際のアプリ開発では「多対多」や「一対一」など、より複雑な関係が必要になる場面も出てきます。そうした高度な構造も、SQLAlchemyであれば柔軟に表現できます。まずは今回の外部キーとリレーションの基本をしっかり押さえておけば、その先の応用にもスムーズに進めるようになります。
サンプルコードでリレーションを振り返る
もう一度、外部キーとリレーションの動きを確認するために、クラスと生徒を登録して一覧を表示する簡単なサンプルコードを紹介します。リレーションを使うことで、クラスから生徒一覧を取り出したり、生徒から所属クラスにアクセスしたりできる点を意識しながら読んでみると理解が深まります。
# クラスと生徒を登録し、関係を使って表示するサンプル
class1 = Classroom(name="二年B組")
db.session.add(class1)
db.session.commit()
student1 = Student(name="高橋一郎", classroom_id=class1.id)
student2 = Student(name="中村真由", classroom_id=class1.id)
db.session.add(student1)
db.session.add(student2)
db.session.commit()
# クラスから生徒一覧を取得
classroom = Classroom.query.first()
print("クラス名:", classroom.name)
for stu in classroom.students:
print("所属生徒:", stu.name)
# 生徒から所属クラス名を取得
s = Student.query.first()
print("生徒:", s.name, "の所属クラスは", s.classroom.name)
このようにSQLAlchemyのリレーションを使うと、テーブル間の情報を簡潔なコードで安全に扱えるようになります。外部キーがしっかり設定されていることで、どのデータがどこにつながっているのかが明確になり、アプリの動作も安定し、データの整合性も自然と守られます。特にクラスから生徒の一覧を取り出す場面は実務でも非常によく使われるため、しっかり理解しておくと後々大きな力になります。
学んだ内容を整理しながらさらに理解を深める
リレーションを設定する際のポイントを振り返ると、外部キーの指定、relationshipの設定、backrefの使い方、そしてマイグレーションでの反映などが重要でした。こうした項目を一つひとつ確実に押さえておくことで、データベースとのつながりが自然に理解できるようになります。また、実際のアプリケーションでは、ユーザー、記事、コメント、カテゴリなど多くのテーブルが複雑に関わりあうため、外部キーを正しく設定することでアプリ全体の構造がはっきり見え、拡張や修正も行いやすくなります。 データベースの世界では、関係性を表す設計がとても重要です。この考え方に慣れていくと、アプリ全体の動きを整理しながら組み立てる楽しさも大きく広がっていきます。今後さらに高度なアプリを作る際にも、このリレーションの仕組みは必ず役立ちます。今回取り上げた内容をぜひ自分のコードに活かしながら、理解を深めていってください。
生徒
「先生、外部キーって最初はむずかしそうに感じましたが、例え話で聞くと急に身近になって理解しやすくなりました!」
先生
「そうでしょう。データベースの仕組みも、日常の仕組みと同じように考えると案外すっと入ってきます。特にクラスと生徒の例はわかりやすい関係なので、リレーション理解の第一歩にはちょうどいいんですよ。」
生徒
「relationshipを使うと、クラスから生徒を取り出したり、生徒からクラスを見たりできるのも便利ですね!」
先生
「その通りです。外部キーとリレーションを使えば、データのつながりをコードの中でも自然に扱えるようになります。これができれば次のステップにも進みやすくなりますよ。」
生徒
「今回の内容をアプリでも試してみます!もっと複雑な関係も扱ってみたいです!」
先生
「いい意欲ですね。その調子でどんどん挑戦していきましょう。」