この記事ではPythonのORMライブラリ、SQLAlchemyを使って複合キーと関連付け(リレーションシップ)について解説します。具体的なコード例、その詳細な解説、及び応用例を2つ以上を含めています。この記事を通じて、SQLAlchemyでより高度なデータモデリングができるようになります。
はじめに
SQLAlchemyはPythonで利用できるORM(Object Relational Mapper)ライブラリの一つであり、データベース操作をPythonicに行えるように設計されています。今回のテーマである「複合キー」と「関連付け」は、多くの実践的なデータベース設計で出くわす概念であり、その理解と正確な実装は非常に重要です。
複合キーとは
複合キーとは、2つ以上のカラム(フィールド)を組み合わせて、レコード(行)を一意に識別するキーのことです。この複合キーを使用する主な理由は、単一のフィールドだけでは一意性が確保できない場合があるからです。
複合キーの設定方法
SQLAlchemyでは、複合キーは`__table_args__`属性を使用して設定します。
from sqlalchemy import Column, Integer, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Example(Base):
__tablename__ = 'example'
id = Column(Integer, primary_key=True)
name = Column(Integer)
age = Column(Integer)
__table_args__ = (
ForeignKeyConstraint(['name', 'age'], ['another_table.name', 'another_table.age']),
)
このコードにより、`name`と`age`を複合キーとして、`another_table`の`name`および`age`フィールドと関連付けが行われます。
関連付け(リレーションシップ)とは
関連付け(リレーションシップ)とは、2つ以上のテーブル間でデータを連携させる方法です。SQLAlchemyでは`relationship()`関数を使用して、Pythonのクラス間での関連付けを設定します。
関連付けの設定方法
関連付けは`relationship()`関数と、`ForeignKey`クラスを使用して設定します。
from sqlalchemy import relationship
class Parent(Base):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
children = relationship("Child")
class Child(Base):
__tablename__ = 'child'
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey('parent.id'))
この例では、`Parent`クラスと`Child`クラスが一対多の関係を持っていることを表しています。
複合キーと関連付けの組み合わせ
複合キーと関連付けを組み合わせる場面も少なくありません。以下はその一例です。
class GrandChild(Base):
__tablename__ = 'grandchild'
id = Column(Integer, primary_key=True)
child_id = Column(Integer)
parent_id = Column(Integer)
__table_args__ = (
ForeignKeyConstraint(['child_id', 'parent_id'], ['child.id', 'parent.id']),
)
parent = relationship("Parent", foreign_keys=[parent_id])
child = relationship("Child", foreign_keys=[child_id])
この例では`GrandChild`が`Parent`と`Child`に対して複合キーを用いた関連付けを行っています。
応用例1:注文と商品
注文(Order)と商品(Product)がある場合、注文詳細(OrderDetail)で複合キーと関連付けを用いることが多いです。
class Order(Base):
__tablename__ = 'order'
id = Column(Integer, primary_key=True)
details = relationship("OrderDetail")
class Product(Base):
__tablename__ = 'product'
id = Column(Integer, primary_key=True)
class OrderDetail(Base):
__tablename__ = 'order_detail'
order_id = Column(Integer, primary_key=True)
product_id = Column(Integer, primary_key=True)
__table_args__ = (
ForeignKeyConstraint(['order_id', 'product_id'], ['order.id', 'product.id']),
)
order = relationship("Order")
product = relationship("Product")
応用例2:多対多の関連付け
多対多の関連付けでは、中間テーブルが必要になります。
class Student(Base):
__tablename__ = 'student'
id = Column(Integer, primary_key=True)
class Course(Base):
__tablename__ = 'course'
id = Column(Integer, primary_key=True)
class Enrollment(Base):
__tablename__ = 'enrollment'
student_id = Column(Integer, primary_key=True)
course_id = Column(Integer, primary_key=True)
__table_args__ = (
ForeignKeyConstraint(['student_id', 'course_id'], ['student.id', 'course.id']),
)
student = relationship("Student")
course = relationship("Course")
まとめ
この記事では、SQLAlchemyでの複合キーと関連付けについて詳細に解説しました。これらの概念はデータベース設計において非常に重要です。特に、
多対多の関連付けや注文と商品のような実務でよく見られるケースで役立ちます。
コメント