Одним из ключевых элементов ORM является возможность моделировать отношения между таблицами. SQLAlchemy предоставляет функцию relationship()
, чтобы облегчить этот процесс.
relationship()
– это функция в SQLAlchemy, которая позволяет устанавливать связи между моделями. Она создает высокоуровневое, Python-ориентированное интерфейсное свойство, которое может быть использовано для выражения отношений ORM в терминах объектов.
relationship()
может быть настроено для однонаправленного или двунаправленного отношения между моделями. В двунаправленном отношении изменения, сделанные с одной стороны, автоматически отражаются на другой.lazy в relationship()
.Давайте рассмотрим пример однонаправленного отношения "один ко многим" между авторами и книгами:
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
Base = declarative_base()
class Author(Base):
__tablename__ = 'authors'
id = Column(Integer, primary_key=True)
name = Column(String)
# Отношение один ко многим с Book
books = relationship("Book", back_populates="author")
class Book(Base):
__tablename__ = 'books'
id = Column(Integer, primary_key=True)
title = Column(String)
author_id = Column(Integer, ForeignKey('authors.id'))
# Обратная ссылка на автора
author = relationship("Author", back_populates="books")
С помощью установленного отношения, можно легко получать связанные объекты:
author = session.query(Author).first()
print(author.books) # Покажет все книги данного автора
book = session.query(Book).first()
print(book.author) # Покажет автора данной книги
Каскадные операции в relationship()
позволяют автоматически передавать операции, такие как удаление или сохранение между связанными объектами. Это особенно полезно, когда у вас есть иерархия связанных объектов и вы хотите, чтобы изменения в родительском объекте автоматически отражались на дочерних объектах.
Например, вы можете настроить отношение таким образом, чтобы при удалении автора все его книги также удалялись:
books = relationship("Book", back_populates="author", cascade="all, delete")
SQLAlchemy предоставляет возможность использовать динамические отношения, что позволяет работать с элементами отношения как с запросами, а не загружать их все в память. Это может быть особенно полезно для больших коллекций.
books = relationship("Book", back_populates="author", lazy='dynamic')
После этого вы можете использовать author.books как запрос, добавляя к нему фильтры, сортировку и другие операции.
Чтобы уменьшить количество запросов к базе данных, SQLAlchemy позволяет выполнить "joined load" для загрузки связанных объектов в одном запросе. Это можно сделать с помощью параметра joinedload
:
from sqlalchemy.orm import joinedload
authors = session.query(Author).options(joinedload(Author.books)).all()
Таким образом, при доступе к author.books
дополнительных запросов к базе данных не будет, так как книги уже будут загружены в память.
Вы также можете управлять порядком, в котором объекты загружаются в отношении, с помощью параметра order_by
:
books = relationship("Book", order_by=Book.title)
Функция relationship()
в SQLAlchemy представляет собой мощный и гибкий механизм, позволяющий управлять связями между моделями в вашей базе данных. Она предоставляет широкий спектр опций и возможностей для оптимизации производительности, управления жизненным циклом объектов и обеспечения интуитивного взаимодействия между объектами на уровне Python. Надеюсь, что этот обзор поможет вам лучше понять и использовать эту функцию в ваших проектах!
Содержание: