Один ко многим
Отношения один ко многим в SQLAlchemy представляют собой общую связь между двумя сущностями, где одна запись в одной таблице связана с несколькими записями в другой таблице. В отношениях "один ко-многим" первичный ключ экземпляра "одной" стороны служит в качестве внешнего ключа в экземпляре "много" стороны, устанавливая иерархическую связь. Этот тип отношений часто используется, когда один экземпляр имеет несколько связанных с ним экземпляров. Например, рассмотрим сценарий, в котором у вас есть модель "Отдел" и модель "Сотрудник". Каждый отдел может иметь несколько сотрудников, но каждый сотрудник принадлежит только к одному отделу. Это типичный пример использования отношений один ко многим.
SQLAlchemy предоставляет удобный способ определения и реализации отношений "один ко-многим". Как и раньше, вы можете использовать функцию отношений в классе модели, представляющем сущность "одной" стороны, и указать параметр back_populates для определения обратной связи. Параметр back_populates обеспечивает двунаправленную навигацию между сущностями.
Чтобы реализовать отношения один ко многим между моделями "Department" и "Employee", определим связь:
class Department(Base):
__tablename__ = 'departments'
id = Column(Integer, primary_key=True)
name = Column(String(50))
employees = relationship('Employee', back_populates='department')
class Employee(Base):
__tablename__ = 'employees'
id = Column(Integer, primary_key=True)
name = Column(String(50))
department_id = Column(Integer, ForeignKey('departments.id'))
department = relationship('Department', back_populates='employees')
В приведенном выше фрагменте кода отношения сотрудников определяются в модели "Department" с использованием функции relationship и параметра back_populates. Это обеспечивает двунаправленную навигацию, обеспечивая легкий доступ к связанным сотрудникам с объекта отдела и наоборот.
Столбец department_id в модели Employee представляет собой ключ, который устанавливает связь с отделом. В отличие от отношений "один к одному", мы не используем параметр uselist=False, так как хотим, чтобы многие сотрудники могли быть связаны с одним отделом. В случае использования используя конструкции SQLAlchemy 2.0 используя аннотации, мы должны будем указать что принимаем список объектов сотрудников.
employees: Mapped[List["Employee"]] = relationship("Employee", backref="department")
Многие ко многим
Эти отношения представляют собой сложную связь между двумя моделями, где несколько записей в одной таблице могут быть связаны с несколькими записями в другой таблице. В отношениях "многие ко многим" для установления связи между двумя моделями используется посредническая таблица. Например, рассмотрим сценарий, в котором у вас есть модель "Студент" и модель "Курс". Каждый студент может записаться на несколько курсов, и на каждом курсе может быть зачислено несколько студентов. Это идеальный вариант использования для отношений "многие ко многим".
SQLAlchemy предоставляет простой способ реализации отношений "многие ко многим". Для этого вам нужно ввести посредническую таблицу, также известную как таблица соединений или таблица ассоциаций, которая фиксирует связи между двумя другими моделями. Эта посредническая таблица содержит внешние ключи обоих объектов, что позволяет установить отношения "многие ко многим".
class StudentCourses(Base):
__tablename__ = 'student_courses'
id = Column(Integer, primary_key=True)
student_id = Column(Integer, ForeignKey('students.id'))
course_id = Column(Integer, ForeignKey('courses.id'))
class Student(Base):
__tablename__ = 'students'
id = Column(Integer, primary_key=True)
name = Column(String(50))
courses = relationship('Course', secondary=StudentCourses.__table__, back_populates='students')
class Course(Base):
__tablename__ = 'courses'
id = Column(Integer, primary_key=True)
name = Column(String(50))
students = relationship('Student', secondary=StudentCourses.__table__, back_populates='courses')
В приведенном выше фрагменте кода таблица student_courses определяется как класс StudentCourses, наследующийся также от Base. Таблица представлена с помощью двух столбцов, student_id и course_id, оба из них действуют как посторонние ключи, ссылающиеся на соответствующие таблицы.
Модели Student и Course затем используют StudentCourses.__table__ в качестве вторичного параметра(secondary) в своих определениях отношений для установления отношений многие-ко-многим.
В результате будут созданы следующие таблицы:
В заключение, SQLAlchemy предоставляет мощную и гибкую структуру для управления отношениями в ваших веб-приложениях. В следующем шаге мы на практике продолжим работать с таблицами, чтобы получить более глубокое понимание, добавив связи в наши модели.