下面详细介绍 SQLAlchemy 里单对单级联、单对多级联和多对多级联的实现,以及对应的 CRUD 操作,同时给出完整的代码示例。
单对单级联
实现思路
单对单关系意味着一个父对象只关联一个子对象,子对象也只关联一个父对象。可以通过设置 relationship 中的 uselist=False 来表示单对单关系,并且使用 cascade 参数实现级联操作。
代码示例
- from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
- from sqlalchemy.orm import sessionmaker, relationship
- from sqlalchemy.ext.declarative import declarative_base
- # 创建基类
- Base = declarative_base()
- # 定义单对单关系的模型
- class Parent(Base):
- __tablename__ = 'parent'
- id = Column(Integer, primary_key=True)
- name = Column(String)
- # 单对单关系,设置级联操作
- child = relationship("Child", back_populates="parent", uselist=False, cascade="all, delete-orphan")
- class Child(Base):
- __tablename__ = 'child'
- id = Column(Integer, primary_key=True)
- name = Column(String)
- parent_id = Column(Integer, ForeignKey('parent.id'))
- parent = relationship("Parent", back_populates="child")
- # 创建数据库引擎
- engine = create_engine('sqlite:///test.db')
- # 创建表
- Base.metadata.create_all(engine)
- # 创建会话
- Session = sessionmaker(bind=engine)
- session = Session()
- # 创建操作
- def create_one_to_one():
- parent = Parent(name='Parent')
- child = Child(name='Child')
- parent.child = child
- session.add(parent)
- session.commit()
- return parent
- # 读取操作
- def read_one_to_one():
- parent = session.query(Parent).first()
- if parent:
- print(f"Parent: {parent.name}, Child: {parent.child.name if parent.child else 'No child'}")
- return parent
- # 更新操作
- def update_one_to_one():
- parent = session.query(Parent).first()
- if parent:
- parent.name = 'Updated Parent'
- if parent.child:
- parent.child.name = 'Updated Child'
- session.commit()
- return parent
- # 删除操作
- def delete_one_to_one():
- parent = session.query(Parent).first()
- if parent:
- session.delete(parent)
- session.commit()
复制代码 单对多级联
实现思路
单对多关系表示一个父对象可以关联多个子对象,子对象只关联一个父对象。使用 relationship 建立关联,cascade 参数实现级联操作。
代码示例
- # 定义单对多关系的模型
- class Team(Base):
- __tablename__ = 'team'
- id = Column(Integer, primary_key=True)
- name = Column(String)
- # 单对多关系,设置级联操作
- players = relationship("Player", back_populates="team", cascade="all, delete-orphan")
- class Player(Base):
- __tablename__ = 'player'
- id = Column(Integer, primary_key=True)
- name = Column(String)
- team_id = Column(Integer, ForeignKey('team.id'))
- team = relationship("Team", back_populates="players")
- # 创建操作
- def create_one_to_many():
- team = Team(name='Team A')
- player1 = Player(name='Player 1')
- player2 = Player(name='Player 2')
- team.players.extend([player1, player2])
- session.add(team)
- session.commit()
- return team
- # 读取操作
- def read_one_to_many():
- team = session.query(Team).first()
- if team:
- print(f"Team: {team.name}, Players: {[player.name for player in team.players]}")
- return team
- # 更新操作
- def update_one_to_many():
- team = session.query(Team).first()
- if team:
- team.name = 'Updated Team'
- for player in team.players:
- player.name = f"Updated {player.name}"
- session.commit()
- return team
- # 删除操作
- def delete_one_to_many():
- team = session.query(Team).first()
- if team:
- session.delete(team)
- session.commit()
复制代码 多对多级联
实现思路
多对多关系需要一个中间表来关联两个实体。通过 relationship 的 secondary 参数指定中间表,并使用 cascade 实现级联操作。
代码示例
- # 定义中间表
- association_table = Table('association', Base.metadata,
- Column('student_id', Integer, ForeignKey('student.id')),
- Column('course_id', Integer, ForeignKey('course.id'))
- )
- # 定义多对多关系的模型
- class Student(Base):
- __tablename__ = 'student'
- id = Column(Integer, primary_key=True)
- name = Column(String)
- # 多对多关系,设置级联操作
- courses = relationship("Course", secondary=association_table, back_populates="students", cascade="all, delete")
- class Course(Base):
- __tablename__ = 'course'
- id = Column(Integer, primary_key=True)
- name = Column(String)
- students = relationship("Student", secondary=association_table, back_populates="courses")
- # 创建操作
- def create_many_to_many():
- student = Student(name='Student')
- course1 = Course(name='Course 1')
- course2 = Course(name='Course 2')
- student.courses.extend([course1, course2])
- session.add(student)
- session.commit()
- return student
- # 读取操作
- def read_many_to_many():
- student = session.query(Student).first()
- if student:
- print(f"Student: {student.name}, Courses: {[course.name for course in student.courses]}")
- return student
- # 更新操作
- def update_many_to_many():
- student = session.query(Student).first()
- if student:
- student.name = 'Updated Student'
- for course in student.courses:
- course.name = f"Updated {course.name}"
- session.commit()
- return student
- # 删除操作
- def delete_many_to_many():
- student = session.query(Student).first()
- if student:
- session.delete(student)
- session.commit()
复制代码 测试代码
- if __name__ == "__main__":
- # 单对单关系操作
- print("One-to-One Relationship:")
- create_one_to_one()
- read_one_to_one()
- update_one_to_one()
- read_one_to_one()
- delete_one_to_one()
- # 单对多关系操作
- print("\nOne-to-Many Relationship:")
- create_one_to_many()
- read_one_to_many()
- update_one_to_many()
- read_one_to_many()
- delete_one_to_many()
- # 多对多关系操作
- print("\nMany-to-Many Relationship:")
- create_many_to_many()
- read_many_to_many()
- update_many_to_many()
- read_many_to_many()
- delete_many_to_many()
- session.close()
复制代码 代码解释
- 单对单关系:Parent 和 Child 模型通过 relationship 建立一对一关联,uselist=False 明确为单对单,cascade="all, delete-orphan" 确保父对象删除时子对象也被删除。
- 单对多关系:Team 和 Player 模型建立一对多关联,Team 可关联多个 Player,同样使用 cascade="all, delete-orphan" 实现级联删除。
- 多对多关系:Student 和 Course 通过中间表 association_table 建立多对多关联,cascade="all, delete" 保证删除学生时相关课程关联也被删除。
注意事项
- 上述代码使用 SQLite 数据库,你可以根据需求更换数据库引擎。
- 每次操作完成后记得提交会话(session.commit())和关闭会话(session.close())。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |