РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
508 of 711 menu

Функция association_proxy

Функция association_proxy создает атрибут-прокси, который позволяет обращаться к полям связанного объекта напрямую через родительский объект, минуя промежуточную ассоциативную таблицу. Первым параметром передается имя существующего relationship-атрибута, вторым - имя целевого атрибута связанного объекта. Третьим необязательным параметром можно передать creator и getset_factory для тонкой настройки поведения прокси.

Синтаксис

from sqlalchemy.ext.associationproxy import association_proxy association_proxy(target_collection, attr, [creator])

Пример

Давайте создадим две модели, связанные отношением многие-ко-многим через ассоциативную таблицу, и применим association_proxy для удобного доступа к тегам статьи:

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, Table from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship from sqlalchemy.ext.associationproxy import association_proxy class Base(DeclarativeBase): pass article_tag = Table( 'article_tag', Base.metadata, Column('article_id', ForeignKey('articles.id'), primary_key=True), Column('tag_id', ForeignKey('tags.id'), primary_key=True) ) class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] tags: Mapped[list['Tag']] = relationship(secondary=article_tag) tag_names = association_proxy('tags', 'name') class Tag(Base): __tablename__ = 'tags' id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) from sqlalchemy.orm import Session with Session(engine) as session: article = Article(title='article') article.tag_names.append('python') article.tag_names.append('sqlalchemy') session.add(article) session.commit() res = session.query(Article).first() print(res.tag_names)

Результат выполнения кода:

['python', 'sqlalchemy']

Пример

Давайте убедимся, что запись через прокси создает новые связанные объекты автоматически, а чтение дает прямые значения атрибутов:

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, Table from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, Session from sqlalchemy.ext.associationproxy import association_proxy class Base(DeclarativeBase): pass article_tag = Table( 'article_tag', Base.metadata, Column('article_id', ForeignKey('articles.id'), primary_key=True), Column('tag_id', ForeignKey('tags.id'), primary_key=True) ) class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] tags: Mapped[list['Tag']] = relationship(secondary=article_tag) tag_names = association_proxy('tags', 'name') class Tag(Base): __tablename__ = 'tags' id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: article = Article(title='article') article.tag_names.append('sqlite') session.add(article) session.commit() tag = session.query(Tag).first() print(tag.name) print(article.tags[0].name)

Результат выполнения кода:

"sqlite" "sqlite"

Смотрите также

  • функцию relationship,
    которая создает связь между моделями
  • параметр backref,
    который создает обратную ссылку на родителя
  • параметр foreign,
    который задает внешний ключ связи
  • загрузку selectinload,
    которая эффективно подгружает связанные объекты
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить