web-dev-qa-db-ja.com

Flask / SQLAlchemy-多対多の関係の関連付けモデルと関連付けテーブルの違いは?

私はFlaskメガチュートリアルからこのことを学び始めました。彼が多対多の関係に入ると、彼は次のような関連付けテーブルを作成します。

followers = db.Table('followers',
    db.Column('follower_id', db.Integer, db.ForeignKey('user.id')),
    db.Column('followed_id', db.Integer, db.ForeignKey('user.id'))
)

モデル間の特定の関連付けに関するメタデータを追加する方法を探していたところ、このようなものを関連付けテーブルに保存できることがわかりました。しかし、この例では、関連付けテーブルが実際のモデルになっているようです。 。

class DepartmentEmployeeLink(Base):
    __tablename__ = 'department_employee_link'
    department_id = Column(Integer, ForeignKey('department.id'), primary_key=True)
    employee_id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
    extra_data = Column(String(256))
    department = relationship(Department, backref=backref("employee_assoc"))
    employee = relationship(Employee, backref=backref("department_assoc"))

これら2つの方法の違いは何ですか?メタデータを関連付けテーブルに格納するためにモデルメソッドが必要ですか、それともトップメソッドでも同じことができますか?

ありがとう!

20
Chockomonkey

申し訳ありませんが、SQLAlchemyのドキュメントで答えに出くわしました...

https://docs.sqlalchemy.org/en/latest/orm/basic_relationships.html#many-to-many

...違いを明示的に定義する場合:

多対多は、2つのクラス間に関連テーブルを追加します。

association_table = Table('association', Base.metadata,
    Column('left_id', Integer, ForeignKey('left.id')),
    Column('right_id', Integer, ForeignKey('right.id'))
)

アソシエーションオブジェクトパターンは、多対多のバリエーションです。これは、アソシエーションテーブルに、左右のテーブルへの外部キー以外の追加の列が含まれている場合に使用されます。二次引数を使用する代わりに、新しいクラスを関連付けテーブルに直接マップします。

class Association(Base):
    __tablename__ = 'association'
    left_id = Column(Integer, ForeignKey('left.id'), primary_key=True)
    right_id = Column(Integer, ForeignKey('right.id'), primary_key=True)

    extra_data = Column(String(50))

    left = relationship('Left', backref=backref('right_association'))
    right = relationship('Right', backref=backref('left_association'))

「Right」と「Left」はテーブルであり、通常は次のように定義されます。

class Left(Base):
    __tablename__ = 'left'
    id = Column(Integer, primary_key = True)
    ...

class Right(Base):
    __tablename__ = 'right'
    id = Column(Integer, primary_key = True)
    ...

したがって、基本的には、関連付けに何かを格納する必要がある場合にこの追加情報を参照する関連付けオブジェクトを作成します。それ以外の場合は、ORMレイヤーを使用する必要はなく、関連付けテーブルを作成するだけです。

27
Chockomonkey