<commit_before>.. _inheritance_toplevel:

Mapping Class Inheritance Hierarchies
======================================

SQLAlchemy supports three forms of inheritance: **single table inheritance**,
where several types of classes are represented by a single table, **concrete table
inheritance**, where each type of class is represented by independent tables,
and **joined
table inheritance**, where the class hierarchy is broken up
among dependent tables, each class represented by its own table that only
includes those attributes local to that class.

The most common forms of inheritance are single and joined table, while
concrete inheritance presents more configurational challenges.

When mappers are configured in an inheritance relationship, SQLAlchemy has the
ability to load elements :term:`polymorphically`, meaning that a single query can
return objects of multiple types.

Joined Table Inheritance
-------------------------

In joined table inheritance, each class along a particular classes' list of
parents is represented by a unique table. The total set of attributes for a
particular instance is represented as a join along all tables in its
inheritance path. Here, we first define the ``Employee`` class.
This table will contain a primary key column (or columns), and a column
for each attribute that's represented by ``Employee``. In this case it's just
``name``::

    class Employee(Base):
        __tablename__ = 'employee'
        id = Column(Integer, primary_key=True)
        name = Column(String(50))
        type = Column(String(50))

        __mapper_args__ = {
            'polymorphic_identity':'employee',
            'polymorphic_on':type
        }

The mapped table also has a column called ``type``.   The purpose of
this column is to act as the **discriminator**, and stores a value
which indicates the type of object represented within the row. The column may
be of any datatype, though string and integer are the most common.

The discriminator column is only needed if polymorphic loading is
desired, as is usually the case.   It is not strictly necessary that
it be present directly on the base mapped table, and can instead be defined on a
derived select statement that's used when the class is queried;
however, this is a much more sophisticated configuration scenario.

The mapping receives additional arguments via the ``__mapper_args__``
dictionary.   Here the ``type`` column is explicitly stated as the
discriminator column, and the **polymorphic identity** of ``employee``
is also given; this is the value that will be
stored in the polymorphic discriminator column for instances of this
class.

We next define ``Engineer`` and ``Manager`` subclasses of ``Employee``.
Each contains columns that represent the attributes unique to the subclass
they represent. Each table also must contain a primary key column (or
columns), and in most cases a foreign key reference to the parent table::

    class Engineer(Employee):
        __tablename__ = 'engineer'
        id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
        engineer_name = Column(String(30))

        __mapper_args__ = {
            'polymorphic_identity':'engineer',
        }

    class Manager(Person):
        __tablename__ = 'manager'
        id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
        manager_name = Column(String(30))

        __mapper_args__ = {
            'polymorphic_identity':'manager',
        }

It is standard practice that the same column is used for both the role
of primary key as well as foreign key to the parent table,
and that the column is also named the same as that of the parent table.
However, both of these practices are optional.  Separate columns may be used for
primary key and parent-relationship, the column may be named differently than
that of the parent, and even a custom join condition can be specified between
parent and child tables instead of using a foreign key.

.. topic:: Joined inheritance primary keys
<commit_msg>typo in joined table inheritance docs see #2641<commit_after>.. _inheritance_toplevel:

Mapping Class Inheritance Hierarchies
======================================

SQLAlchemy supports three forms of inheritance: **single table inheritance**,
where several types of classes are represented by a single table, **concrete table
inheritance**, where each type of class is represented by independent tables,
and **joined
table inheritance**, where the class hierarchy is broken up
among dependent tables, each class represented by its own table that only
includes those attributes local to that class.

The most common forms of inheritance are single and joined table, while
concrete inheritance presents more configurational challenges.

When mappers are configured in an inheritance relationship, SQLAlchemy has the
ability to load elements :term:`polymorphically`, meaning that a single query can
return objects of multiple types.

Joined Table Inheritance
-------------------------

In joined table inheritance, each class along a particular classes' list of
parents is represented by a unique table. The total set of attributes for a
particular instance is represented as a join along all tables in its
inheritance path. Here, we first define the ``Employee`` class.
This table will contain a primary key column (or columns), and a column
for each attribute that's represented by ``Employee``. In this case it's just
``name``::

    class Employee(Base):
        __tablename__ = 'employee'
        id = Column(Integer, primary_key=True)
        name = Column(String(50))
        type = Column(String(50))

        __mapper_args__ = {
            'polymorphic_identity':'employee',
            'polymorphic_on':type
        }

The mapped table also has a column called ``type``.   The purpose of
this column is to act as the **discriminator**, and stores a value
which indicates the type of object represented within the row. The column may
be of any datatype, though string and integer are the most common.

The discriminator column is only needed if polymorphic loading is
desired, as is usually the case.   It is not strictly necessary that
it be present directly on the base mapped table, and can instead be defined on a
derived select statement that's used when the class is queried;
however, this is a much more sophisticated configuration scenario.

The mapping receives additional arguments via the ``__mapper_args__``
dictionary.   Here the ``type`` column is explicitly stated as the
discriminator column, and the **polymorphic identity** of ``employee``
is also given; this is the value that will be
stored in the polymorphic discriminator column for instances of this
class.

We next define ``Engineer`` and ``Manager`` subclasses of ``Employee``.
Each contains columns that represent the attributes unique to the subclass
they represent. Each table also must contain a primary key column (or
columns), and in most cases a foreign key reference to the parent table::

    class Engineer(Employee):
        __tablename__ = 'engineer'
        id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
        engineer_name = Column(String(30))

        __mapper_args__ = {
            'polymorphic_identity':'engineer',
        }

    class Manager(Employee):
        __tablename__ = 'manager'
        id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
        manager_name = Column(String(30))

        __mapper_args__ = {
            'polymorphic_identity':'manager',
        }

It is standard practice that the same column is used for both the role
of primary key as well as foreign key to the parent table,
and that the column is also named the same as that of the parent table.
However, both of these practices are optional.  Separate columns may be used for
primary key and parent-relationship, the column may be named differently than
that of the parent, and even a custom join condition can be specified between
parent and child tables instead of using a foreign key.

.. topic:: Joined inheritance primary keys

{'fraction_non_alphanumeric': 0.07197720515361744, 'fraction_numerical': 0.002477700693756194, 'mean_word_length': 3.9833333333333334, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '749896', 'n_tokens_mistral': 2004, 'n_tokens_neox': 1882, 'n_words': 1047}