使用 SQLAlchemy 实现数据库关系:一对一与多对多
在开发应用程序时,我们经常需要在数据库中存储不同类型的数据,并且这些数据之间存在一定的关系。SQLAlchemy 提供了一种优雅的方式来处理这些关系,使得我们在编写 Python 代码时可以更加专注于业务逻辑而不是繁琐的 SQL 语句。本文将介绍如何使用 SQLAlchemy 实现一对一和多对多关系。
环境准备
在开始之前,请确保安装了必要的 Python 包,包括 SQLAlchemy 和 pymysql。你可以通过以下命令安装:
bash
深色版本
1pip install sqlalchemy pymysql
假设我们已经有一个 MySQL 数据库,连接字符串如下:
python
深色版本
1DB_URI = "mysql+pymysql://root:123456@127.0.0.1:3306/testsql"
一对一关系 (One-to-One)
一对一关系指的是两个表之间的一条记录只能对应另一条记录。例如,一个用户可以拥有一个电子邮件地址。
实现一对一关系
- 定义模型类 - 使用 SQLAlchemy 的
declarative_base来定义基础类,然后定义具体的模型类。 - 设置外键 - 在子类中定义外键指向父类的主键。
- 建立关系 - 使用
relationship来建立表之间的关系。
示例代码
python
深色版本
1from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
2from sqlalchemy.ext.declarative import declarative_base
3from sqlalchemy.orm import sessionmaker, relationship
4
5DB_URI = "mysql+pymysql://root:123456@127.0.0.1:3306/testsql"
6engine = create_engine(DB_URI)
7Base = declarative_base()
8Session = sessionmaker(bind=engine)
9session = Session()
10
11class User(Base):
12 __tablename__ = 'users'
13 id = Column(Integer, primary_key=True)
14 name = Column(String(50))
15 email = relationship("Email", uselist=False, back_populates="user")
16
17 def __repr__(self):
18 return f"<User(name='{self.name}')>"
19
20class Email(Base):
21 __tablename__ = 'emails'
22 id = Column(Integer, primary_key=True)
23 address = Column(String(50))
24 user_id = Column(Integer, ForeignKey('users.id'))
25 user = relationship("User", back_populates="email")
26
27 def __repr__(self):
28 return f"<Email(address='{self.address}')>"
29
30User.email = relationship(
31 "Email",
32 uselist=False,
33 back_populates="user"
34)
35
36Base.metadata.create_all(engine)
使用一对一关系
现在我们可以创建用户和电子邮件地址,并将它们关联起来。
python
深色版本
1# 创建用户
2user = User(name='John Doe')
3# 创建电子邮件地址
4email = Email(address='john.doe@example.com')
5# 关联用户和电子邮件
6user.email = email
7# 添加到数据库
8session.add(user)
9session.commit()
多对多关系 (Many-to-Many)
多对多关系是指两个表之间的记录可以对应多个记录。例如,一个教师可以教授多门课程,而一门课程也可以有多个教师。
实现多对多关系
- 定义中间表 - 使用
Table定义一个中间表,该表至少包含两个外键,分别指向两个需要关联的表。 - 定义模型类 - 定义两个模型类,并使用
relationship来建立表之间的关系。
示例代码
python
深色版本
1from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, Table
2from sqlalchemy.ext.declarative import declarative_base
3from sqlalchemy.orm import sessionmaker, relationship
4
5DB_URI = "mysql+pymysql://root:123456@127.0.0.1:3306/testsql"
6engine = create_engine(DB_URI)
7Base = declarative_base()
8Session = sessionmaker(bind=engine)
9session = Session()
10
11# 创建一个多对多的关系需要创建一个中间表
12teacher_courses = Table(
13 "teacher_courses",
14 Base.metadata,
15 Column("teacher_id", Integer, ForeignKey("teachers.id"), nullable=False, primary_key=True),
16 Column("course_id", Integer, ForeignKey("courses.id"), nullable=False, primary_key=True)
17)
18
19class Teacher(Base):
20 __tablename__ = 'teachers'
21 id = Column(Integer, primary_key=True)
22 name = Column(String(50))
23 courses = relationship("Course", secondary=teacher_courses, back_populates="teachers")
24
25 def __repr__(self):
26 return f"<Teacher(name='{self.name}')>"
27
28class Course(Base):
29 __tablename__ = 'courses'
30 id = Column(Integer, primary_key=True)
31 name = Column(String(50))
32 teachers = relationship("Teacher", secondary=teacher_courses, back_populates="courses")
33
34 def __repr__(self):
35 return f"<Course(name='{self.name}')>"
36
37Base.metadata.create_all(engine)
使用多对多关系
创建教师和课程,并将它们关联起来。
python
深色版本
1# 创建教师
2teacher1 = Teacher(name='Mr. Smith')
3teacher2 = Teacher(name='Ms. Johnson')
4
5# 创建课程
6course1 = Course(name='Mathematics')
7course2 = Course(name='Physics')
8
9# 关联教师和课程
10teacher1.courses = [course1, course2]
11teacher2.courses = [course1]
12
13# 添加到数据库
14session.add_all([teacher1, teacher2])
15session.commit()
查询关系
你可以轻松地查询关系。
python
深色版本
1# 查询教师及其教授的课程
2teacher = session.query(Teacher).filter_by(name='Mr. Smith').first()
3print(teacher.courses)
4
5# 查询课程及其对应的教师
6course = session.query(Course).filter_by(name='Mathematics').first()
7print(course.teachers)
以上就是使用 SQLAlchemy 实现一对一和多对多关系的基本方法。希望这篇文章能帮助你更好地理解和使用 SQLAlchemy 来管理数据库中的关系。
本文介绍如何使用SQLAlchemy优雅地处理数据库中的一对一与多对多关系。包括环境搭建、模型定义及关系建立等关键步骤。
605

被折叠的 条评论
为什么被折叠?



