使用 SQLAlchemy 实现数据库关系:一对一与多对多

在开发应用程序时,我们经常需要在数据库中存储不同类型的数据,并且这些数据之间存在一定的关系。SQLAlchemy 提供了一种优雅的方式来处理这些关系,使得我们在编写 Python 代码时可以更加专注于业务逻辑而不是繁琐的 SQL 语句。本文将介绍如何使用 SQLAlchemy 实现一对一和多对多关系。

在开始之前,请确保安装了必要的 Python 包,包括 SQLAlchemy pymysql 。你可以通过以下命令安装:

1pip install sqlalchemy pymysql

假设我们已经有一个 MySQL 数据库,连接字符串如下:

python

1DB_URI = "mysql+pymysql://root:[email protected]:3306/testsql"

一对一关系 (One-to-One)

一对一关系指的是两个表之间的一条记录只能对应另一条记录。例如,一个用户可以拥有一个电子邮件地址。

实现一对一关系

  1. 定义模型类 - 使用 SQLAlchemy 的 declarative_base 来定义基础类,然后定义具体的模型类。
  2. 设置外键 - 在子类中定义外键指向父类的主键。
  3. 建立关系 - 使用 relationship 来建立表之间的关系。

python

1from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
2from sqlalchemy.ext.declarative import declarative_base
3from sqlalchemy.orm import sessionmaker, relationship
5DB_URI = "mysql+pymysql://root:[email protected]:3306/testsql"
6engine = create_engine(DB_URI)
7Base = declarative_base()
8Session = sessionmaker(bind=engine)
9session = Session()
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")
17    def __repr__(self):
18        return f"<User(name='{self.name}')>"
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")
27    def __repr__(self):
28        return f"<Email(address='{self.address}')>"
30User.email = relationship(
31    "Email",
32    uselist=False,
33    back_populates="user"
36Base.metadata.create_all(engine)

使用一对一关系

现在我们可以创建用户和电子邮件地址,并将它们关联起来。

python

1# 创建用户
2user = User(name='John Doe')
3# 创建电子邮件地址
4email = Email(address='[email protected]')
5# 关联用户和电子邮件
6user.email = email
7# 添加到数据库
8session.add(user)
9session.commit()

多对多关系 (Many-to-Many)

多对多关系是指两个表之间的记录可以对应多个记录。例如,一个教师可以教授多门课程,而一门课程也可以有多个教师。

实现多对多关系

  1. 定义中间表 - 使用 Table 定义一个中间表,该表至少包含两个外键,分别指向两个需要关联的表。
  2. 定义模型类 - 定义两个模型类,并使用 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
5DB_URI = "mysql+pymysql://root:[email protected]:3306/testsql"
6engine = create_engine(DB_URI)
7Base = declarative_base()
8Session = sessionmaker(bind=engine)
9session = Session()
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)
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")
25    def __repr__(self):
26        return f"<Teacher(name='{self.name}')>"
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")
34    def __repr__(self):
35        return f"<Course(name='{self.name}')>"
37Base.metadata.create_all(engine)

使用多对多关系

创建教师和课程,并将它们关联起来。

python

1# 创建教师
2teacher1 = Teacher(name='Mr. Smith')
3teacher2 = Teacher(name='Ms. Johnson')
5# 创建课程
6course1 = Course(name='Mathematics')
7course2 = Course(name='Physics')
9# 关联教师和课程
10teacher1.courses = [course1, course2]
11teacher2.courses = [course1]
13# 添加到数据库
14session.add_all([teacher1, teacher2])
15session.commit()

你可以轻松地查询关系。

python

1# 查询教师及其教授的课程
2teacher = session.query(Teacher).filter_by(name='Mr. Smith').first()
3print(teacher.courses)
5# 查询课程及其对应的教师
6course = session.query(Course).filter_by(name='Mathematics').first()
7print(course.teachers)

以上就是使用 SQLAlchemy 实现一对一和多对多关系的基本方法。希望这篇文章能帮助你更好地理解和使用 SQLAlchemy 来管理数据库中的关系。

有时候,我们在使用 SQLAlchemy 操作某些 的时候,需要使用外键 关系 来实现 一对多 或者多对多的 关系 引用,以及对多 的联合查询,有序列的uuid值或者自增id值,字符串的分拆等常见处理操作。 1、在 SQLAlchemy 中定义具有嵌套 children 关系 要在 SQLAlchemy 中定义具有嵌套 children 关系 ,如 中包含 id 和 pid 字段,可以使用 relatio... 今天我们就讲讲 sqlalchemy 最后一种 关系 一对一 首先,我们先创建user(父 )、arctire(子 )两张 ,代码如下:#父 class User(Base):    __tablename__ = "user"    id = Column(Integer , primary_key=True , autoincrement=True)    name = Column(String... sqlalchemy 之间 关系 有三种:1、多对多  2、 一对多 3、 一对一 下面就讲讲 sqlalchemy 之间 如何 建立 多对多 关系 。 首先,我们把两个需要做多对多 关系 的模型定义出来,这里以Arctire,Tag模型为例(示例代码如下)class Arctire(Base):      __tablename__ = "arctire"    id = Column(Integer , prima... 最为常见的 关系 就是 一对多 关系 。因为 关系 在它们 建立 之前就已经声明,您可以使用 字符串来指代还没有创建的类(例如如果Person定义了一个到Article的 关系 ,而Article在文件的后面才会声明)。 关系 使用relationship()函数 示。然而外键必须用类 sqlalchemy .schema.ForeignKey来单独声明: class Person(db.Model): id = db.Column(db.Integer, primary_key=True) SQLAlchemy “采用简单的 Python 语言,为高效和高性能的 数据库 访问设计,实现了完整的企业级持久模型”。 SQLAlchemy 的理念是, SQL 数据库 的量级和性能重要于对象集合;而对象集合的抽象又重要于 和行。因此, SQLAlchemy 采用了类似于Java里Hibernate的数据映射模型,而不是其他ORM框架采用的Active Record模型。 其中author_id = db.Column(db.Integer, db.ForeignKey("user.id"))这一句通过外键的方式使得Article 可以访问user 中的id项。在视图函数中,我们创建好articles和user实例后,通过articles.author=user进行绑定。比如我们要创建一张用户 和文章 ,因为用户与文章是 一对多 关系 (一个用户可以有多篇文章,一篇文章往往是一个用户所写)。可以看见成功创建了两个 ,并且author_id和user 的id是一致的。 SQLAlchemy 是一个强大的 Python ORM(对象 关系 映射)库,它允许我们将 数据库 映射到 Python 对象,并提供了丰富的 关系 模型来处理不同类型的 关系 ,包括 一对一 关系 。在本文中,我们将深入探讨 SQLAlchemy 一对一 关系 的概念,以及如何在模型中定义和使用这种 关系 一对一 关系 数据库 中两个 之间 关系 ,其中一个 的每个记录对应另一个 的一个记录,而且每个记录在另一个 中只有一个关联项。