• SQLAlchemy关联表删除策略设置


    目录

    SQLAlchemy关联表

    常用的级联选项

    外键


    SQLAlchemy关联表

    SQLAlchemy 是一个 Python 的 ORM(对象关系映射)库,它允许你在 Python 中使用类来表示数据库中的表,从而更方便地进行数据库操作。在 SQLAlchemy 中,可以使用关联表(relationship)来定义两个表之间的关系,包括一对一、一对多和多对多等关系。

    在定义关联表的时候,你可以设置 cascade 参数来指定在删除记录时的级联行为。

    常用的级联选项

    1. all:删除主记录时,从属记录也会被删除。
    2. save-update:当主记录发生变化时,从属记录会自动保存。
    3. delete-orphan:删除主记录时,从属记录也会被删除,如果从属记录变成了孤儿(没有任何主记录与之关联),也会被删除。

    以下是一个简单的例子,演示了如何在 SQLAlchemy 中设置关联表的删除策略:

    1. from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
    2. from sqlalchemy.ext.declarative import declarative_base
    3. from sqlalchemy.orm import relationship
    4. Base = declarative_base()
    5. class Parent(Base):
    6. __tablename__ = 'parents'
    7. id = Column(Integer, primary_key=True)
    8. name = Column(String)
    9. children = relationship('Child', back_populates='parent', cascade='all, delete-orphan')
    10. class Child(Base):
    11. __tablename__ = 'children'
    12. id = Column(Integer, primary_key=True)
    13. name = Column(String)
    14. parent_id = Column(Integer, ForeignKey('parents.id'))
    15. parent = relationship('Parent', back_populates='children')
    16. # 创建数据库连接
    17. engine = create_engine('sqlite:///example.db')
    18. # 创建表格
    19. Base.metadata.create_all(engine)

     

    • Parent 表中有一个名为 children 的关联关系,它关联到了 Child 类,通过 back_populates 参数指定了反向关系的属性名为 parent,并且设置了级联删除策略为 all, delete-orphan,这表示在删除父记录时,会级联删除子记录,并且也会删除变成孤儿的子记录。

    • Child 表中有一个名为 parent 的关联关系,它关联到了 Parent 类,通过 back_populates 参数指定了反向关系的属性名为 children

    创建了一个 SQLite 数据库连接,并使用 Base.metadata.create_all(engine) 来创建表格。

     

    外键

    使用SQLAlchemy创建外键非常简单。在从表中增加一个字段,指定这个字段外键的是哪个表的哪个字段就可以了。从表中外键的字段,必须和主表的主键字段类型保持一致。

    1. class User(Base):
    2. __tablename__ = 't_user'
    3. id = Column(Integer,primary_key=True,autoincrement=True)
    4. uname = Column(String(50),nullable=False,name='name')
    5. class News(Base):
    6. __tablename__ = 't_news'
    7. id = Column(Integer,primary_key=True,autoincrement=True)
    8. title = Column(String(50),nullable=False)
    9. content = Column(Text,nullable=False)
    10. uid = Column(Integer,ForeignKey('t_user.id',)

    外键约束有以下几项:

    • RESTRICT:若子表中有父表对应的关联数据,删除父表对应数据,会阻止删除。默认项

    • NO ACTION:在MySQL中,同RESTRICT。

    • CASCADE:级联删除。

    • SET NULL:父表对应数据被删除,子表对应数据项会设置为NULL。

     

    1. from sqlalchemy import Column,Integer,String,Text,ForeignKey
    2. from db_util import Base,Session
    3. class User(Base):
    4. __tablename__ = 't_user'
    5. id = Column(Integer,primary_key=True,autoincrement=True)
    6. uname = Column(String(50),nullable=False,name='name')
    7. class News(Base):
    8. __tablename__ = 't_news'
    9. id = Column(Integer,primary_key=True,autoincrement=True)
    10. title = Column(String(50),nullable=False)
    11. content = Column(Text,nullable=False)
    12. # uid = Column(Integer,ForeignKey('t_user.id')) # 默认不让删主表数据
    13. # uid = Column(Integer,ForeignKey('t_user.id',ondelete = 'RESTRICT')) # 默认的策略
    14. # uid = Column(Integer,ForeignKey('t_user.id',ondelete = 'NO ACTION')) # 默认的策略
    15. # uid = Column(Integer,ForeignKey('t_user.id',ondelete = 'CASCADE')) # 级联删除,发主表的数据被删除,子表的里数据也会删除
    16. uid = Column(Integer,ForeignKey('t_user.id',ondelete = 'SET NULL')) # 发现主表数据被删除时,子表的数据列会清空
    17. def create_data():
    18. user = User(uname = 'sxt')
    19. news1 = News(title='python',content='flask',uid = 1)
    20. news2 = News(title='MySQL',content='SQL',uid = 1)
    21. with Session() as ses:
    22. ses.add(user)
    23. ses.commit()
    24. with Session() as ses:
    25. ses.add(news1)
    26. ses.add(news2)
    27. ses.commit()
    28. if __name__ == '__main__':
    29. Base.metadata.create_all()
    30. create_data()

    News 表中,使用了外键 uid 关联到了 t_user.id,并设置了删除策略为 SET NULL,这表示当 t_user 表中的对应记录被删除时,会将 News 表中对应的外键字段(即 uid)设为 NULL

    提供了一个 create_data 函数来创建用户和新闻的示例数据,并在 __main__ 中调用了该函数。

    create_data 函数中,首先创建了一个用户(uname 为 'sxt'),然后创建了两条新闻记录,并分别将 uid 设置为 1,表示这两条新闻属于用户 1。

    然后你通过 Session 来提交了这些数据。

    最后,在 __main__ 中调用了 Base.metadata.create_all() 来创建数据库表结构,然后调用了 create_data() 函数来插入示例数据。

     

  • 相关阅读:
    开源python双屏图片浏览器软件
    算法竞赛进阶指南 基本算法 0x01 位运算
    KNN算法实现
    SELF-RAG: 让LLM集检索,生成跟评判等多种能力于一身
    【C++算法】is_partitioned、partition_copy和partition_point
    Linux内核宏Container_Of
    【Vue3】Vue3中监视watch和watchEffect使用(图文+代码)
    决策树介绍
    K8S Pod Sidecar 应用场景之一-加入 NGINX Sidecar 做反代和 web 服务器
    信息系统漏洞与风险管理制度
  • 原文地址:https://blog.csdn.net/m0_67093160/article/details/133324009