Одним из основных преимуществ SQLAlchemy является её мощный и гибкий ORM (Object-Relational Mapping), который позволяет создавать и манипулировать данными в базе данных, используя Python-классы. Одним из наиболее часто используемых типов отношений в базах данных является отношение One-to-Many.
Отношение One-to-Many (один ко многим) описывает связь, при которой одна запись в таблице может быть связана с множеством записей в другой таблице. Например, один автор может написать множество книг, но каждая книга имеет только одного автора.
Для реализации отношения One-to-Many в SQLAlchemy используется комбинация relationship
и ForeignKey
. Рассмотрим пример:
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)
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
может иметь несколько книг Book
, но каждая книга принадлежит только одному автору.
engine = create_engine('sqlite:///books.db')
Base.metadata.create_all(engine)
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
session = Session()
# Создание автора и книг
tolkien = Author(name="J.R.R. Tolkien")
tolkien.books = [Book(title="The Fellowship of the Ring"), Book(title="The Two Towers")]
session.add(tolkien)
session.commit()
# Запрос автора и его книг
author = session.query(Author).filter_by(name="J.R.R. Tolkien").one()
for book in author.books:
print(book.title)
Вместо явного определения отношения с обеих сторон, вы можете использовать backref
для создания двунаправленного отношения между двумя моделями с одной стороны:
class Book(Base):
__tablename__ = 'books'
id = Column(Integer, primary_key=True)
title = Column(String)
author_id = Column(Integer, ForeignKey('authors.id'))
author = relationship("Author", backref="books")
Теперь у модели Author
автоматически появится атрибут books
, благодаря параметру backref
.
Если у вас есть необходимость автоматически сортировать связанные записи, вы можете использовать параметр order_by
:
class Author(Base):
# ...
books = relationship("Book", order_by=Book.title, back_populates="author")
Как упомянуто ранее, cascade позволяет управлять жизненным циклом дочерних объектов. Например, cascade="all, delete-orphan"
гарантирует, что дочерние объекты будут удалены, если их родительский объект будет удален, и что любые "сироты" (объекты, которые больше не имеют родительского объекта) также будут удалены.
В SQLAlchemy вы можете определить, как и когда связанные объекты будут загружаться из базы данных. Вот некоторые из опций:
Отношение One-to-Many - основной строительный блок при моделировании баз данных. SQLAlchemy делает его реализацию простой и интуитивно понятной, предоставляя множество инструментов для эффективной работы с данными.
Содержание: