Учебники

SQLAlchemy ORM — построение отношений

Этот сеанс описывает создание другой таблицы, которая связана с уже существующей в нашей базе данных. Таблица клиентов содержит основные данные клиентов. Теперь нам нужно создать таблицу счетов, которая может содержать любое количество счетов, принадлежащих клиенту. Это случай отношения один ко многим.

Используя декларативное, мы определяем эту таблицу вместе с отображаемым классом Invoices, как показано ниже —

from sqlalchemy import create_engine, ForeignKey, Column, Integer, String
engine = create_engine('sqlite:///sales.db', echo = True)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
from sqlalchemy.orm import relationship

class Customer(Base):
   __tablename__ = 'customers'

   id = Column(Integer, primary_key = True)
   name = Column(String)
   address = Column(String)
   email = Column(String)

class Invoice(Base):
   __tablename__ = 'invoices'
   
   id = Column(Integer, primary_key = True)
   custid = Column(Integer, ForeignKey('customers.id'))
   invno = Column(Integer)
   amount = Column(Integer)
   customer = relationship("Customer", back_populates = "invoices")

Customer.invoices = relationship("Invoice", order_by = Invoice.id, back_populates = "customer")
Base.metadata.create_all(engine)

Это отправит запрос CREATE TABLE на движок SQLite, как показано ниже:

CREATE TABLE invoices (
   id INTEGER NOT NULL,
   custid INTEGER,
   invno INTEGER,
   amount INTEGER,
   PRIMARY KEY (id),
   FOREIGN KEY(custid) REFERENCES customers (id)
)

Мы можем проверить, что новая таблица создается в sales.db с помощью инструмента SQLiteStudio.

Sales.db Новая таблица

Класс Invoices применяет конструкцию ForeignKey к атрибуту custid. Эта директива указывает, что значения в этом столбце должны быть ограничены значениями, указанными в столбце id в таблице клиентов. Это основная особенность реляционных баз данных, и это «клей», который преобразует несвязанный набор таблиц, чтобы иметь богатые перекрывающиеся отношения.

Вторая директива, известная как отношением (), сообщает ORM, что класс Invoice должен быть связан с классом Customer с помощью атрибута Invoice.customer. Отношение () использует отношения внешнего ключа между этими двумя таблицами, чтобы определить природу этой связи, определяя, что это много к одной.

Дополнительная директива отношения () помещается в сопоставленный класс Customer под атрибутом Customer.invoices. Параметр relations.back_populate назначается для ссылки на имена дополнительных атрибутов, так что каждая связь () может принимать интеллектуальное решение относительно той же самой связи, которая выражена в обратном порядке. С одной стороны, Invoices.customer ссылается на экземпляр Invoices, а с другой стороны, Customer.invoices ссылается на список экземпляров Customer.

Функция отношений является частью API отношений пакета ORM SQLAlchemy. Он обеспечивает связь между двумя сопоставленными классами. Это соответствует родительскому или дочернему табличному отношению.

Ниже приведены основные шаблоны отношений —

Один ко многим

Отношение «один ко многим» относится к родителю с помощью внешнего ключа на дочерней таблице. Затем для родителя указывается отношение () как ссылка на коллекцию элементов, представленных дочерним элементом. Параметр relations.back_poplates используется для установления двунаправленного отношения «один-ко-многим», где «обратная» сторона — это «многие к одному».

Много к одному

С другой стороны, отношение «многие к одному» помещает внешний ключ в родительскую таблицу для ссылки на дочернего элемента. Связи () объявляется на родителя, где будет создан новый атрибут скалярного хранения. Здесь снова параметр отношениях.back_poplates используется для двунаправленного поведения.

Один к одному

Отношения «один к одному», по сути, являются двусторонними отношениями по своей природе. Флаг списка использования указывает размещение скалярного атрибута вместо коллекции на стороне «многие» отношения. Чтобы преобразовать отношения один-ко-многим в тип отношения один-к-одному, установите для параметра uselist значение false.

Много ко многим

Отношение «многие ко многим» устанавливается путем добавления таблицы ассоциации, связанной с двумя классами, путем определения атрибутов с их внешними ключами. На это указывает вторичный аргумент отношения (). Обычно в таблице используется объект MetaData, связанный с декларативным базовым классом, так что директивы ForeignKey могут находить удаленные таблицы, с которыми можно связываться. Параметр relations.back_poplates для каждой взаимосвязи () устанавливает двунаправленную связь. Обе стороны отношений содержат коллекцию.