FlaskとSQLiteを使用した多対多(many-to-many)リレーションシップの実装について、完全かつ包括的な記事を日本語でご紹介します。
FlaskとSQLiteのセットアップ
まず、Flaskアプリケーションを作成し、SQLiteをデータベースとして使用する準備をします。以下の手順に従ってください。
- FlaskとSQLAlchemyのインストール
FlaskとSQLAlchemyをインストールするには、次のコマンドを実行します:
bashpip install flask flask_sqlalchemy
これでFlaskとSQLAlchemyがインストールされました。SQLAlchemyはORM(Object-Relational Mapping)ライブラリで、SQLiteと簡単にやり取りできます。
- Flaskアプリケーションの作成
次に、Flaskアプリケーションを作成し、SQLiteデータベースを設定します。以下は基本的なFlaskアプリケーションのコードです。
pythonfrom flask import Flask
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)
if __name__ == "__main__":
app.run(debug=True)
上記のコードでは、SQLALCHEMY_DATABASE_URIでSQLiteデータベースファイルapp.dbを指定しています。
多対多リレーションシップの実装
多対多リレーションシップを実現するために、3つのモデルを作成します。ここでは「ユーザー(User)」と「グループ(Group)」という2つのテーブルを例に説明します。ユーザーは複数のグループに参加でき、1つのグループにも複数のユーザーが所属します。この関係を表すために、交差テーブル(association table)を使用します。
- UserモデルとGroupモデルの作成
pythonclass User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
groups = db.relationship('Group', secondary='user_group', back_populates='users')
class Group(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
users = db.relationship('User', secondary='user_group', back_populates='groups')
class UserGroup(db.Model):
__tablename__ = 'user_group'
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
group_id = db.Column(db.Integer, db.ForeignKey('group.id'), primary_key=True)
ここで、UserとGroupはdb.relationshipを使って相互にリレーションを作成しています。secondaryオプションを使って、交差テーブル(user_group)を指定しています。UserGroupは、user_idとgroup_idのペアが主キーとなる交差テーブルです。
- データベースの作成
次に、データベースとテーブルを作成するために、以下のコマンドをPythonシェルまたはFlaskアプリケーション内で実行します。
pythonwith app.app_context():
db.create_all()
これにより、User、Group、UserGroupのテーブルがSQLiteデータベースに作成されます。
データの追加とリレーションの設定
次に、ユーザーとグループをデータベースに追加し、リレーションシップを設定します。
- データの挿入
python# ユーザーとグループを作成
user1 = User(name="Alice")
user2 = User(name="Bob")
group1 = Group(name="Group A")
group2 = Group(name="Group B")
# ユーザーをグループに追加
user1.groups.append(group1)
user1.groups.append(group2)
user2.groups.append(group1)
# データをコミット
db.session.add(user1)
db.session.add(user2)
db.session.add(group1)
db.session.add(group2)
db.session.commit()
上記のコードでは、user1とuser2がそれぞれgroup1とgroup2に参加しています。appendメソッドを使ってリレーションを設定し、その後、session.commit()でデータベースに保存しています。
- データの取得
リレーションシップを使用してデータを取得する方法です。
python# 特定のユーザーが参加しているグループを取得
alice = User.query.filter_by(name="Alice").first()
for group in alice.groups:
print(group.name)
# 特定のグループに所属しているユーザーを取得
group_a = Group.query.filter_by(name="Group A").first()
for user in group_a.users:
print(user.name)
このコードでは、aliceが参加しているグループを表示し、group_aに参加しているユーザーを表示しています。
FlaskのAPIエンドポイントでリレーションを使用
FlaskアプリケーションでAPIエンドポイントを作成して、リレーションシップを操作することも可能です。以下は、ユーザーとグループを表示する簡単なAPIの例です。
pythonfrom flask import jsonify
@app.route('/users')
def get_users():
users = User.query.all()
return jsonify([user.name for user in users])
@app.route('/groups')
def get_groups():
groups = Group.query.all()
return jsonify([group.name for group in groups])
これで、/usersエンドポイントで全ユーザーの名前を、/groupsエンドポイントで全グループの名前を取得できます。
結論
FlaskとSQLiteを使った多対多のリレーションシップの実装は、SQLAlchemyを使うことで非常に簡単に行うことができます。db.relationshipを使ってリレーションを定義し、交差テーブルを使用することで、複数のテーブル間の関連を管理できます。この方法を使うことで、データベース設計の柔軟性を持ちながら、簡潔で効率的なコードを書くことができます。
