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

Атрибут polymorphic_identity класса Mapper

Атрибут polymorphic_identity класса Mapper задает строковый идентификатор для полиморфного подкласса при наследовании моделей. Этот идентификатор сохраняется в столбце, указанном в атрибуте polymorphic_on, и позволяет SQLAlchemy при выборке строки из таблицы определить, какому классу-наследнику она принадлежит. Значением атрибута может быть любая строка или целое число, однозначно идентифицирующее подкласс.

Синтаксис

__mapper_args__ = {'polymorphic_identity': 'identity_value'}

Пример

Давайте создадим базовый класс Article и подкласс DraftArticle, указав для подкласса идентификатор draft:

<+python+> from sqlalchemy import create_engine, String from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) status: Mapped[str] = mapped_column(String(50)) __mapper_args__ = { 'polymorphic_on': status, 'polymorphic_identity': 'article' } class DraftArticle(Article): __mapper_args__ = { 'polymorphic_identity': 'draft' } engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: draft = DraftArticle(title='article', status='draft') session.add(draft) session.commit() res = session.query(Article).all() for article in res: print(type(article).__name__, article.title, article.status) <-python+>

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

"DraftArticle article draft"

Пример

Давайте добавим второй подкласс PublishedArticle с идентификатором published и убедимся, что SQLAlchemy корректно различает типы:

<+python+> from sqlalchemy import create_engine, String from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) status: Mapped[str] = mapped_column(String(50)) __mapper_args__ = { 'polymorphic_on': status, 'polymorphic_identity': 'article' } class DraftArticle(Article): __mapper_args__ = { 'polymorphic_identity': 'draft' } class PublishedArticle(Article): __mapper_args__ = { 'polymorphic_identity': 'published' } engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: session.add(DraftArticle(title='article', status='draft')) session.add(PublishedArticle(title='article', status='published')) session.commit() res = session.query(Article).order_by(Article.id).all() for article in res: print(type(article).__name__, article.status) <-python+>

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

"DraftArticle draft" "PublishedArticle published"

Пример

Давайте посмотрим, какой SQL-запрос генерирует SQLAlchemy при выборке полиморфных объектов:

<+python+> from sqlalchemy import create_engine, String from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) status: Mapped[str] = mapped_column(String(50)) __mapper_args__ = { 'polymorphic_on': status, 'polymorphic_identity': 'article' } class DraftArticle(Article): __mapper_args__ = { 'polymorphic_identity': 'draft' } engine = create_engine('sqlite:///:memory:', echo=True) Base.metadata.create_all(engine) with Session(engine) as session: session.add(DraftArticle(title='article', status='draft')) session.commit() res = session.query(DraftArticle).all() print(len(res)) <-python+>

Итоговый SQL запрос:

SELECT articles.id AS articles_id, articles.title AS articles_title, articles.status AS articles_status FROM articles WHERE articles.status IN (?)

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

  • атрибут polymorphic_on,
    который указывает столбец-дискриминатор
  • класс Mapper,
    который представляет отображение класса
  • атрибут class_,
    который хранит отображаемый класс
  • атрибут columns,
    который содержит коллекцию столбцов
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить