1、一对一
class Parent(Base): __tablename__ = 'parent' id = Column(Integer, primary_key=True) child = relationship("Child", uselist=False, back_populates="parent") class Child(Base): __tablename__ = 'child' id = Column(Integer, primary_key=True) parent_id = Column(Integer, ForeignKey('parent.id')) parent = relationship("Parent", back_populates="child")
2、一对多
一对多关系将外键放在引用父对象的子表上。 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'))
要在一对多中建立双向关系,其中“反向”侧是多对一,请指定一个附加relationship()
并使用relationship.back_populates
参数连接两者:
class Parent(Base): __tablename__ = 'parent' id = Column(Integer, primary_key=True) children = relationship("Child", back_populates="parent") class Child(Base): __tablename__ = 'child' id = Column(Integer, primary_key=True) parent_id = Column(Integer, ForeignKey('parent.id')) parent = relationship("Parent", back_populates="children")
Child
将获得parent
具有多对一语义的属性。
或者,该backref
选项可用于单个relationship()
而不是使用 back_populates
:
class Parent(Base): __tablename__ = 'parent' id = Column(Integer, primary_key=True) children = relationship("Child", backref="parent")
3、多对一
多对一将外键放在引用该子对象的父表中。 relationship()
在父级上声明,将创建一个新的标量持有属性:
class Parent(Base): __tablename__ = 'parent' id = Column(Integer, primary_key=True) child_id = Column(Integer, ForeignKey('child.id')) child = relationship("Child") class Child(Base): __tablename__ = 'child' id = Column(Integer, primary_key=True)
通过添加relationship()
并relationship.back_populates
在两个方向上应用参数来实现双向行为:
class Parent(Base): __tablename__ = 'parent' id = Column(Integer, primary_key=True) child_id = Column(Integer, ForeignKey('child.id')) child = relationship("Child", back_populates="parents") class Child(Base): __tablename__ = 'child' id = Column(Integer, primary_key=True) parents = relationship("Parent", back_populates="child")
或者,backref
参数可以应用于单个relationship()
,例如Parent.child
:
class Parent(Base): __tablename__ = 'parent' id = Column(Integer, primary_key=True) child_id = Column(Integer, ForeignKey('child.id')) child = relationship("Child", backref="parents")
4、多对多
Many to Many在两个类之间添加了一个关联表。关联表由secondary
参数表示 relationship()
。通常,Table
使用MetaData
与声明性基类关联的对象,以便ForeignKey
指令可以定位要与之链接的远程表:
association_table = Table('association', Base.metadata, Column('left_id', Integer, ForeignKey('left.id')), Column('right_id', Integer, ForeignKey('right.id')) ) class Parent(Base): __tablename__ = 'left' id = Column(Integer, primary_key=True) children = relationship("Child", secondary=association_table) class Child(Base): __tablename__ = 'right' id = Column(Integer, primary_key=True)
对于双向关系,关系的两侧都包含一个集合。指定using relationship.back_populates
,并为每个relationship()
指定公共关联表:
association_table = Table('association', Base.metadata, Column('left_id', Integer, ForeignKey('left.id')), Column('right_id', Integer, ForeignKey('right.id')) ) class Parent(Base): __tablename__ = 'left' id = Column(Integer, primary_key=True) children = relationship( "Child", secondary=association_table, back_populates="parents") class Child(Base): __tablename__ = 'right' id = Column(Integer, primary_key=True) parents = relationship( "Parent", secondary=association_table, back_populates="children")
当使用backref
参数代替时 relationship.back_populates
,backref会自动使用相同的secondary
参数作为反向关系:
association_table = Table('association', Base.metadata, Column('left_id', Integer, ForeignKey('left.id')), Column('right_id', Integer, ForeignKey('right.id')) ) class Parent(Base): __tablename__ = 'left' id = Column(Integer, primary_key=True) children = relationship("Child", secondary=association_table, backref="parents") class Child(Base): __tablename__ = 'right' id = Column(Integer, primary_key=True)
5、自联表
自关联最常见就是评论盖楼和地址的三级联动了,下面一评论盖楼为例:
一个评论下面有很多追加的评论,这是可以通过记录父评论的id就可以一环扣一环形成完整了评论楼层
class Category(db.Model): """商品分类表""" __tablename__ = 'category' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(100), unique=True) parent_id = db.Column(db.Integer, db.ForeignKey('category.id')) parent = db.relationship('Category', remote_side=[id]) #自关联 leavel = db.Column(db.SmallInteger, default=1, comment='级别') state = db.Column(db.SmallInteger, default=1, comment='状态 1--有效 0--无效') def __repr__(self): return "" % self.name