【问题标题】:Flask/SQLAlchemy - Difference between association model and association table for many-to-many relationship?Flask/SQLAlchemy - 多对多关系的关联模型和关联表之间的区别?
【发布时间】:2015-08-05 01:45:29
【问题描述】:

我从 Flask Mega 教程开始学习这些东西。当他进入多对多关系时,他会创建一个如下所示的关联表:

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"))

这两种方法有什么区别?是需要model方法在关联表中存储元数据还是同样的事情可以用top方法来完成?

谢谢!

【问题讨论】:

    标签: flask sqlalchemy many-to-many flask-sqlalchemy model-associations


    【解决方案1】:

    抱歉,我终于在 SQLAlchemy 文档中偶然发现了答案......

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

    ...他们明确定义了差异:

    Many to Many 在两个类之间添加一个关联表。

    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 层,你可以只创建一个关联表。

    【讨论】:

    • @oski86 不客气!对我来说,找出两者之间的差异是一个重要的时刻。这一切都在对象模式中extra_data列的应用中!如果您不需要绑定到特定模型对的额外数据,则不需要关联对象——更简单的关联表就足够了!
    • @Chockomonkey 正在寻找这个。请为我清除这个。这会像现在“关联”和其他模型之间的一对多关系吗?在那种情况下,我们还必须在这些模型中定义关系吗?会有很大帮助。
    • @NewGuy 好问题,感谢提问!您发现我的回答乏善可陈,此后我用充实的关系字段对其进行了更新,并为清楚起见还添加了一些表定义。希望这会有所帮助!
    • @user2682863 我今天调查了这个。文档表明 backref 在这种情况下是合法使用的,实际上最终会调用 back_populates 本身。它是一种简写,因为当在 Association 对象中的关系定义中使用 backref 时,它不需要在 LeftRight 模型中显式定义关系。有人可能会争辩说显式更好,但实际上两者都可以。
    猜你喜欢
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 2017-10-30
    • 2015-05-08
    • 1970-01-01
    • 2017-08-30
    • 1970-01-01
    相关资源
    最近更新 更多