一对多和多对一关联

比如:作者和文章之间, 部门和员工之间都是一对多的关联关系。反过来就是:多对一的关联关系

 

1、定义外键约束


定义关系的第一步是创建外键。外键是(foreign key)用来在 A 表存储 B 表的主键值以便和 B 表建立
联系的关系字段。
因为外键只能存储单一数据(标量),所以外键总是在 “多” 这一侧定义,多篇文章属于同 一个作
者,所以我们需要为每篇文章添加外键存储作者的主键值以指向 对应的作者。在 Article 模型中,我们
定义一个 author_id 字段作为外键:
注意ForeginKey的参数是<表名>.<键名>,而不是<类名>.<字段名>

 

# 多对一关联的外键
dept_id: Mapped[Optional[int]] = mapped_column(ForeignKey('t_dept.id'))

 

2、定义关联属性和双向关联

我们在 Author 类中定义了集合关系属性 articles ,用来获取某个作者拥有的多篇文章记录。
在某些情况下,你也许希望能在 Article 类中定义 一个类似的 author 关系属性,当被调用时返
回对应的作者记录,而这种两侧都添加关系属性获取对方记录的关系我们称之为 双向关系。双向关系
并不是必须的,但在某些情况下会非常方便。

# 多对一关联的属性, back_populates写对方模型类中的关联属性名字
dept: Mapped[Optional['Dept']] = relationship(back_populates='emp_list')
# 一对多的关联属性
emp_list: Mapped[List['Employee']] = relationship(back_populates='dept',
cascade='save-update')

 

3、级联操作


cascade,默认选项为save-update:
• 一:save-update:默认选项,在添加一条数据的时候,会把其他和次数据关联的数据都添加到数
据库中,这种行为就是save-update属性决定的
• 二:delete:表示当删除某一个模型中的数据的时候,也删除掉使用relationship和此数据关联的
数据

三:delete-orphan:表示当对一个ORM对象解除了父表中的关联对象的时候,自己便会被删除,
如果父表的数据被删除,同样自己也会被删除,这个选项只能用在一对多上,不能用在多对多和多
对一上,并且使用的时候还需要在子模型的relationship中增加参数:single_parent=True
• 四:merge(合并):默认选项,当在使用session.merge合并一个对象的时候,会将使用了
relationship相关联的对象也进行merge操作
• 五:expunge:移除操作的时候,会将相关联的对象也进行移除,这个操作只是从session中移
除,并不会正则从数据库删除
• 六:all:对 save-update、merge、refresh-expire、expunge、delete 这几种的缩写

 

4、树形结构的自关联

 

class Dept(Base):
"""部门的模型类"""
__tablename__ = 't_dept'
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
name: Mapped[str] = mapped_column(String(20), unique=True, nullable=False)
address: Mapped[Optional[str]] = mapped_column(String(50))
# 一对多的关联属性
emp_list: Mapped[List['Employee']] = relationship(back_populates='dept',
cascade='save-update')
# 自己和自己外键
pid: Mapped[Optional[int]] = mapped_column(ForeignKey('t_dept.id'))
# 自己和自己一对多的关联的属性
children: Mapped[List['Dept']] = relationship(back_populates='parent')
# 自己和自己多对一的关联的属性 remote_side = [id], 写到多的一端。(非列表)
parent: Mapped[Optional['Dept']] = relationship(back_populates='children',
remote_side=[id])

维护一对多自关联关系的时候(relationship),必须加入:remote_side= [id]

posted @ 2024-07-09 16:34  yongheng999  阅读(110)  评论(0)    收藏  举报