第五节:SQLAlchemy的关联
一、ORM中的一对多/多对一
SQLAlchemy提供了一个 relationship
,这个类可以定义属性,以后在访问相关联的表的时候就直接可以通过属性访问的方式就可以访问得到了。另外,可以通过 back_populates
来指定反向访问的属性名称。
注意ForeginKey的参数是<表名>.<键名>,而不是<类名>.<字段名>
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 这几种的缩写
二、自关联
我们说数据表关系时,默认说的是数据表之间的关系「一对多、一对一、多对多等等」。而在实际应用中常常会遇到数据表内的关联,比如现在互联中的一个名词「关注者」和「被关注者」,他们都在用户范围内,只是两个用户之间的关系。或者是:父部门,和子部门。
children: Mapped[List['Dept']] = relationship(back_populates='parent', remote_side=[id])
维护1对多自关联关系的时候(relationship),必须加入:remote_side= [id]
三、一对一关联
关系很简单:一个用户对应一张身份证,一张身份证属于一个用户。
emp: Mapped['Employee'] = relationship(back_populates='id_card', single_parent=True)
其中:single_parent=True
表示子表,只关联父表的一行记录。
四、多对多关联
数据库中多对多的关系,主要有下面三个步骤
- 定义一个中间表保存两个表的主键
- 定义多对多关系的两个表的模型
- 给每个模型都添加一个访问对方的属性
注意在relationship
中指定中间表
middle_table = Table( # 中间表
't_emp_role',
Base.metadata,
Column('emp_id', ForeignKey('t_emp.id'), primary_key=True),
Column('role_id', ForeignKey('t_role.id'), primary_key=True),
)