%PDF- %PDF-
| Direktori : /usr/share/doc/alt-python27-sqlalchemy-1.3.6/doc/orm/extensions/declarative/ |
| Current File : //usr/share/doc/alt-python27-sqlalchemy-1.3.6/doc/orm/extensions/declarative/inheritance.html |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>
Inheritance Configuration
—
SQLAlchemy 1.3 Documentation
</title>
<!-- begin iterate through site-imported + sphinx environment css_files -->
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/docs.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/changelog.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/sphinx_paramlinks.css" type="text/css" />
<!-- end iterate through site-imported + sphinx environment css_files -->
<!-- begin layout.mako headers -->
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<link rel="copyright" title="Copyright" href="../../../copyright.html" />
<link rel="top" title="SQLAlchemy 1.3 Documentation" href="../../../index.html" />
<link rel="up" title="Declarative" href="index.html" />
<link rel="next" title="Mixin and Custom Base Classes" href="mixins.html" />
<link rel="prev" title="Table Configuration" href="table_config.html" />
<!-- end layout.mako headers -->
</head>
<body>
<div id="docs-container">
<div id="docs-top-navigation-container" class="body-background">
<div id="docs-header">
<div id="docs-version-header">
Release: <span class="version-num">1.3.6</span>
| Release Date: July 21, 2019
</div>
<h1>SQLAlchemy 1.3 Documentation</h1>
</div>
</div>
<div id="docs-body-container">
<div id="fixed-sidebar" class="withsidebar">
<div id="docs-sidebar-popout">
<h3><a href="../../../index.html">SQLAlchemy 1.3 Documentation</a></h3>
<p id="sidebar-topnav">
<a href="../../../contents.html">Contents</a> |
<a href="../../../genindex.html">Index</a>
</p>
<div id="sidebar-search">
<form class="search" action="../../../search.html" method="get">
<label>
Search terms:
<input type="text" placeholder="search..." name="q" size="12" />
</label>
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div id="docs-sidebar">
<div id="sidebar-banner">
</div>
<div id="docs-sidebar-inner">
<h3>
<a href="../../index.html" title="SQLAlchemy ORM">SQLAlchemy ORM</a>
</h3>
<ul>
<li><span class="link-container"><a class="reference external" href="../../tutorial.html">Object Relational Tutorial</a></span></li>
<li><span class="link-container"><a class="reference external" href="../../mapper_config.html">Mapper Configuration</a></span></li>
<li><span class="link-container"><a class="reference external" href="../../relationships.html">Relationship Configuration</a></span></li>
<li><span class="link-container"><a class="reference external" href="../../loading_objects.html">Loading Objects</a></span></li>
<li><span class="link-container"><a class="reference external" href="../../session.html">Using the Session</a></span></li>
<li><span class="link-container"><a class="reference external" href="../../extending.html">Events and Internals</a></span></li>
<li><span class="link-container"><a class="reference external" href="../index.html">ORM Extensions</a></span><ul>
<li><span class="link-container"><a class="reference external" href="../associationproxy.html">Association Proxy</a></span></li>
<li><span class="link-container"><a class="reference external" href="../automap.html">Automap</a></span></li>
<li><span class="link-container"><a class="reference external" href="../baked.html">Baked Queries</a></span></li>
<li><span class="link-container"><a class="reference external" href="index.html">Declarative</a></span><ul>
<li><span class="link-container"><a class="reference external" href="basic_use.html">Basic Use</a></span></li>
<li><span class="link-container"><a class="reference external" href="relationships.html">Configuring Relationships</a></span></li>
<li><span class="link-container"><a class="reference external" href="table_config.html">Table Configuration</a></span></li>
<li class="selected"><span class="link-container"><strong>Inheritance Configuration</strong><a class="paramlink headerlink reference internal" href="#">¶</a></span><ul>
<li><span class="link-container"><a class="reference external" href="#joined-table-inheritance">Joined Table Inheritance</a></span></li>
<li><span class="link-container"><a class="reference external" href="#single-table-inheritance">Single Table Inheritance</a></span><ul>
<li><span class="link-container"><a class="reference external" href="#resolving-column-conflicts">Resolving Column Conflicts</a></span></li>
</ul>
</li>
<li><span class="link-container"><a class="reference external" href="#concrete-table-inheritance">Concrete Table Inheritance</a></span></li>
</ul>
</li>
<li><span class="link-container"><a class="reference external" href="mixins.html">Mixin and Custom Base Classes</a></span></li>
<li><span class="link-container"><a class="reference external" href="api.html">Declarative API</a></span></li>
</ul>
</li>
<li><span class="link-container"><a class="reference external" href="../mutable.html">Mutation Tracking</a></span></li>
<li><span class="link-container"><a class="reference external" href="../orderinglist.html">Ordering List</a></span></li>
<li><span class="link-container"><a class="reference external" href="../horizontal_shard.html">Horizontal Sharding</a></span></li>
<li><span class="link-container"><a class="reference external" href="../hybrid.html">Hybrid Attributes</a></span></li>
<li><span class="link-container"><a class="reference external" href="../indexable.html">Indexable</a></span></li>
<li><span class="link-container"><a class="reference external" href="../instrumentation.html">Alternate Class Instrumentation</a></span></li>
</ul>
</li>
<li><span class="link-container"><a class="reference external" href="../../examples.html">ORM Examples</a></span></li>
</ul>
</div>
</div>
</div>
<div id="docs-body" class="withsidebar" >
<div class="section" id="inheritance-configuration">
<span id="declarative-inheritance"></span><h1>Inheritance Configuration<a class="headerlink" href="#inheritance-configuration" title="Permalink to this headline">¶</a></h1>
<p>Declarative supports all three forms of inheritance as intuitively
as possible. The <code class="docutils literal notranslate"><span class="pre">inherits</span></code> mapper keyword argument is not needed
as declarative will determine this from the class itself. The various
“polymorphic” keyword arguments are specified using <code class="docutils literal notranslate"><span class="pre">__mapper_args__</span></code>.</p>
<div class="admonition seealso">
<p class="admonition-title">See also</p>
<p>This section describes some specific details on how the Declarative system
interacts with SQLAlchemy ORM inheritance configuration. See
<a class="reference internal" href="../../inheritance.html"><span class="std std-ref">Mapping Class Inheritance Hierarchies</span></a> for a general introduction to inheritance
mapping.</p>
</div>
<div class="section" id="joined-table-inheritance">
<h2>Joined Table Inheritance<a class="headerlink" href="#joined-table-inheritance" title="Permalink to this headline">¶</a></h2>
<p>Joined table inheritance is defined as a subclass that defines its own
table:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Person</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s1">'people'</span>
<span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">discriminator</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s1">'type'</span><span class="p">,</span> <span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">))</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_on'</span><span class="p">:</span> <span class="n">discriminator</span><span class="p">}</span>
<span class="k">class</span> <span class="nc">Engineer</span><span class="p">(</span><span class="n">Person</span><span class="p">):</span>
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s1">'engineers'</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_identity'</span><span class="p">:</span> <span class="s1">'engineer'</span><span class="p">}</span>
<span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s1">'people.id'</span><span class="p">),</span> <span class="n">primary_key</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">primary_language</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">))</span></pre></div>
</div>
<p>Note that above, the <code class="docutils literal notranslate"><span class="pre">Engineer.id</span></code> attribute, since it shares the
same attribute name as the <code class="docutils literal notranslate"><span class="pre">Person.id</span></code> attribute, will in fact
represent the <code class="docutils literal notranslate"><span class="pre">people.id</span></code> and <code class="docutils literal notranslate"><span class="pre">engineers.id</span></code> columns together,
with the “Engineer.id” column taking precedence if queried directly.
To provide the <code class="docutils literal notranslate"><span class="pre">Engineer</span></code> class with an attribute that represents
only the <code class="docutils literal notranslate"><span class="pre">engineers.id</span></code> column, give it a different attribute name:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Engineer</span><span class="p">(</span><span class="n">Person</span><span class="p">):</span>
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s1">'engineers'</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_identity'</span><span class="p">:</span> <span class="s1">'engineer'</span><span class="p">}</span>
<span class="n">engineer_id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s1">'id'</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s1">'people.id'</span><span class="p">),</span>
<span class="n">primary_key</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">primary_language</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">))</span></pre></div>
</div>
</div>
<div class="section" id="single-table-inheritance">
<span id="declarative-single-table"></span><h2>Single Table Inheritance<a class="headerlink" href="#single-table-inheritance" title="Permalink to this headline">¶</a></h2>
<p>Single table inheritance is defined as a subclass that does not have
its own table; you just leave out the <code class="docutils literal notranslate"><span class="pre">__table__</span></code> and <code class="docutils literal notranslate"><span class="pre">__tablename__</span></code>
attributes:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Person</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s1">'people'</span>
<span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">discriminator</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s1">'type'</span><span class="p">,</span> <span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">))</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_on'</span><span class="p">:</span> <span class="n">discriminator</span><span class="p">}</span>
<span class="k">class</span> <span class="nc">Engineer</span><span class="p">(</span><span class="n">Person</span><span class="p">):</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_identity'</span><span class="p">:</span> <span class="s1">'engineer'</span><span class="p">}</span>
<span class="n">primary_language</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">))</span></pre></div>
</div>
<p>When the above mappers are configured, the <code class="docutils literal notranslate"><span class="pre">Person</span></code> class is mapped
to the <code class="docutils literal notranslate"><span class="pre">people</span></code> table <em>before</em> the <code class="docutils literal notranslate"><span class="pre">primary_language</span></code> column is
defined, and this column will not be included in its own mapping.
When <code class="docutils literal notranslate"><span class="pre">Engineer</span></code> then defines the <code class="docutils literal notranslate"><span class="pre">primary_language</span></code> column, the
column is added to the <code class="docutils literal notranslate"><span class="pre">people</span></code> table so that it is included in the
mapping for <code class="docutils literal notranslate"><span class="pre">Engineer</span></code> and is also part of the table’s full set of
columns. Columns which are not mapped to <code class="docutils literal notranslate"><span class="pre">Person</span></code> are also excluded
from any other single or joined inheriting classes using the
<code class="docutils literal notranslate"><span class="pre">exclude_properties</span></code> mapper argument. Below, <code class="docutils literal notranslate"><span class="pre">Manager</span></code> will have
all the attributes of <code class="docutils literal notranslate"><span class="pre">Person</span></code> and <code class="docutils literal notranslate"><span class="pre">Manager</span></code> but <em>not</em> the
<code class="docutils literal notranslate"><span class="pre">primary_language</span></code> attribute of <code class="docutils literal notranslate"><span class="pre">Engineer</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Manager</span><span class="p">(</span><span class="n">Person</span><span class="p">):</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_identity'</span><span class="p">:</span> <span class="s1">'manager'</span><span class="p">}</span>
<span class="n">golf_swing</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">))</span></pre></div>
</div>
<p>The attribute exclusion logic is provided by the
<code class="docutils literal notranslate"><span class="pre">exclude_properties</span></code> mapper argument, and declarative’s default
behavior can be disabled by passing an explicit <code class="docutils literal notranslate"><span class="pre">exclude_properties</span></code>
collection (empty or otherwise) to the <code class="docutils literal notranslate"><span class="pre">__mapper_args__</span></code>.</p>
<div class="section" id="resolving-column-conflicts">
<span id="declarative-column-conflicts"></span><h3>Resolving Column Conflicts<a class="headerlink" href="#resolving-column-conflicts" title="Permalink to this headline">¶</a></h3>
<p>Note above that the <code class="docutils literal notranslate"><span class="pre">primary_language</span></code> and <code class="docutils literal notranslate"><span class="pre">golf_swing</span></code> columns
are “moved up” to be applied to <code class="docutils literal notranslate"><span class="pre">Person.__table__</span></code>, as a result of their
declaration on a subclass that has no table of its own. A tricky case
comes up when two subclasses want to specify <em>the same</em> column, as below:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Person</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s1">'people'</span>
<span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">discriminator</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s1">'type'</span><span class="p">,</span> <span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">))</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_on'</span><span class="p">:</span> <span class="n">discriminator</span><span class="p">}</span>
<span class="k">class</span> <span class="nc">Engineer</span><span class="p">(</span><span class="n">Person</span><span class="p">):</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_identity'</span><span class="p">:</span> <span class="s1">'engineer'</span><span class="p">}</span>
<span class="n">start_date</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">DateTime</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">Manager</span><span class="p">(</span><span class="n">Person</span><span class="p">):</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_identity'</span><span class="p">:</span> <span class="s1">'manager'</span><span class="p">}</span>
<span class="n">start_date</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">DateTime</span><span class="p">)</span></pre></div>
</div>
<p>Above, the <code class="docutils literal notranslate"><span class="pre">start_date</span></code> column declared on both <code class="docutils literal notranslate"><span class="pre">Engineer</span></code> and <code class="docutils literal notranslate"><span class="pre">Manager</span></code>
will result in an error:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>sqlalchemy.exc.ArgumentError: Column 'start_date' on class
<class '__main__.Manager'> conflicts with existing
column 'people.start_date'</pre></div>
</div>
<p>In a situation like this, Declarative can’t be sure
of the intent, especially if the <code class="docutils literal notranslate"><span class="pre">start_date</span></code> columns had, for example,
different types. A situation like this can be resolved by using
<a class="reference internal" href="api.html#sqlalchemy.ext.declarative.declared_attr" title="sqlalchemy.ext.declarative.declared_attr"><code class="xref py py-class docutils literal notranslate"><span class="pre">declared_attr</span></code></a> to define the <a class="reference internal" href="../../../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">Column</span></code></a> conditionally, taking
care to return the <strong>existing column</strong> via the parent <code class="docutils literal notranslate"><span class="pre">__table__</span></code> if it
already exists:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="k">import</span> <span class="n">declared_attr</span>
<span class="k">class</span> <span class="nc">Person</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s1">'people'</span>
<span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">discriminator</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s1">'type'</span><span class="p">,</span> <span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">))</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_on'</span><span class="p">:</span> <span class="n">discriminator</span><span class="p">}</span>
<span class="k">class</span> <span class="nc">Engineer</span><span class="p">(</span><span class="n">Person</span><span class="p">):</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_identity'</span><span class="p">:</span> <span class="s1">'engineer'</span><span class="p">}</span>
<span class="nd">@declared_attr</span>
<span class="k">def</span> <span class="nf">start_date</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
<span class="s2">"Start date column, if not present already."</span>
<span class="k">return</span> <span class="n">Person</span><span class="o">.</span><span class="n">__table__</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'start_date'</span><span class="p">,</span> <span class="n">Column</span><span class="p">(</span><span class="n">DateTime</span><span class="p">))</span>
<span class="k">class</span> <span class="nc">Manager</span><span class="p">(</span><span class="n">Person</span><span class="p">):</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_identity'</span><span class="p">:</span> <span class="s1">'manager'</span><span class="p">}</span>
<span class="nd">@declared_attr</span>
<span class="k">def</span> <span class="nf">start_date</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
<span class="s2">"Start date column, if not present already."</span>
<span class="k">return</span> <span class="n">Person</span><span class="o">.</span><span class="n">__table__</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'start_date'</span><span class="p">,</span> <span class="n">Column</span><span class="p">(</span><span class="n">DateTime</span><span class="p">))</span></pre></div>
</div>
<p>Above, when <code class="docutils literal notranslate"><span class="pre">Manager</span></code> is mapped, the <code class="docutils literal notranslate"><span class="pre">start_date</span></code> column is
already present on the <code class="docutils literal notranslate"><span class="pre">Person</span></code> class. Declarative lets us return
that <a class="reference internal" href="../../../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">Column</span></code></a> as a result in this case, where it knows to skip
re-assigning the same column. If the mapping is mis-configured such
that the <code class="docutils literal notranslate"><span class="pre">start_date</span></code> column is accidentally re-assigned to a
different table (such as, if we changed <code class="docutils literal notranslate"><span class="pre">Manager</span></code> to be joined
inheritance without fixing <code class="docutils literal notranslate"><span class="pre">start_date</span></code>), an error is raised which
indicates an existing <a class="reference internal" href="../../../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><code class="xref py py-class docutils literal notranslate"><span class="pre">Column</span></code></a> is trying to be re-assigned to
a different owning <a class="reference internal" href="../../../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><code class="xref py py-class docutils literal notranslate"><span class="pre">Table</span></code></a>.</p>
<p>The same concept can be used with mixin classes (see
<a class="reference internal" href="mixins.html#declarative-mixins"><span class="std std-ref">Mixin and Custom Base Classes</span></a>):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Person</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s1">'people'</span>
<span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">discriminator</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s1">'type'</span><span class="p">,</span> <span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">))</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_on'</span><span class="p">:</span> <span class="n">discriminator</span><span class="p">}</span>
<span class="k">class</span> <span class="nc">HasStartDate</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="nd">@declared_attr</span>
<span class="k">def</span> <span class="nf">start_date</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">__table__</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'start_date'</span><span class="p">,</span> <span class="n">Column</span><span class="p">(</span><span class="n">DateTime</span><span class="p">))</span>
<span class="k">class</span> <span class="nc">Engineer</span><span class="p">(</span><span class="n">HasStartDate</span><span class="p">,</span> <span class="n">Person</span><span class="p">):</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_identity'</span><span class="p">:</span> <span class="s1">'engineer'</span><span class="p">}</span>
<span class="k">class</span> <span class="nc">Manager</span><span class="p">(</span><span class="n">HasStartDate</span><span class="p">,</span> <span class="n">Person</span><span class="p">):</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_identity'</span><span class="p">:</span> <span class="s1">'manager'</span><span class="p">}</span></pre></div>
</div>
<p>The above mixin checks the local <code class="docutils literal notranslate"><span class="pre">__table__</span></code> attribute for the column.
Because we’re using single table inheritance, we’re sure that in this case,
<code class="docutils literal notranslate"><span class="pre">cls.__table__</span></code> refers to <code class="docutils literal notranslate"><span class="pre">Person.__table__</span></code>. If we were mixing joined-
and single-table inheritance, we might want our mixin to check more carefully
if <code class="docutils literal notranslate"><span class="pre">cls.__table__</span></code> is really the <a class="reference internal" href="../../../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><code class="xref py py-class docutils literal notranslate"><span class="pre">Table</span></code></a> we’re looking for.</p>
</div>
</div>
<div class="section" id="concrete-table-inheritance">
<span id="declarative-concrete-table"></span><h2>Concrete Table Inheritance<a class="headerlink" href="#concrete-table-inheritance" title="Permalink to this headline">¶</a></h2>
<p>Concrete is defined as a subclass which has its own table and sets the
<code class="docutils literal notranslate"><span class="pre">concrete</span></code> keyword argument to <code class="docutils literal notranslate"><span class="pre">True</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Person</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s1">'people'</span>
<span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">name</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">))</span>
<span class="k">class</span> <span class="nc">Engineer</span><span class="p">(</span><span class="n">Person</span><span class="p">):</span>
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s1">'engineers'</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'concrete'</span><span class="p">:</span><span class="kc">True</span><span class="p">}</span>
<span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">primary_language</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">))</span>
<span class="n">name</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">))</span></pre></div>
</div>
<p>Usage of an abstract base class is a little less straightforward as it
requires usage of <a class="reference internal" href="../../mapping_api.html#sqlalchemy.orm.util.polymorphic_union" title="sqlalchemy.orm.util.polymorphic_union"><code class="xref py py-func docutils literal notranslate"><span class="pre">polymorphic_union()</span></code></a>,
which needs to be created with the <a class="reference internal" href="../../../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><code class="xref py py-class docutils literal notranslate"><span class="pre">Table</span></code></a> objects
before the class is built:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">engineers</span> <span class="o">=</span> <span class="n">Table</span><span class="p">(</span><span class="s1">'engineers'</span><span class="p">,</span> <span class="n">Base</span><span class="o">.</span><span class="n">metadata</span><span class="p">,</span>
<span class="n">Column</span><span class="p">(</span><span class="s1">'id'</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="kc">True</span><span class="p">),</span>
<span class="n">Column</span><span class="p">(</span><span class="s1">'name'</span><span class="p">,</span> <span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">)),</span>
<span class="n">Column</span><span class="p">(</span><span class="s1">'primary_language'</span><span class="p">,</span> <span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">))</span>
<span class="p">)</span>
<span class="n">managers</span> <span class="o">=</span> <span class="n">Table</span><span class="p">(</span><span class="s1">'managers'</span><span class="p">,</span> <span class="n">Base</span><span class="o">.</span><span class="n">metadata</span><span class="p">,</span>
<span class="n">Column</span><span class="p">(</span><span class="s1">'id'</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="kc">True</span><span class="p">),</span>
<span class="n">Column</span><span class="p">(</span><span class="s1">'name'</span><span class="p">,</span> <span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">)),</span>
<span class="n">Column</span><span class="p">(</span><span class="s1">'golf_swing'</span><span class="p">,</span> <span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">))</span>
<span class="p">)</span>
<span class="n">punion</span> <span class="o">=</span> <span class="n">polymorphic_union</span><span class="p">({</span>
<span class="s1">'engineer'</span><span class="p">:</span><span class="n">engineers</span><span class="p">,</span>
<span class="s1">'manager'</span><span class="p">:</span><span class="n">managers</span>
<span class="p">},</span> <span class="s1">'type'</span><span class="p">,</span> <span class="s1">'punion'</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">Person</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
<span class="n">__table__</span> <span class="o">=</span> <span class="n">punion</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_on'</span><span class="p">:</span><span class="n">punion</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">type</span><span class="p">}</span>
<span class="k">class</span> <span class="nc">Engineer</span><span class="p">(</span><span class="n">Person</span><span class="p">):</span>
<span class="n">__table__</span> <span class="o">=</span> <span class="n">engineers</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_identity'</span><span class="p">:</span><span class="s1">'engineer'</span><span class="p">,</span> <span class="s1">'concrete'</span><span class="p">:</span><span class="kc">True</span><span class="p">}</span>
<span class="k">class</span> <span class="nc">Manager</span><span class="p">(</span><span class="n">Person</span><span class="p">):</span>
<span class="n">__table__</span> <span class="o">=</span> <span class="n">managers</span>
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'polymorphic_identity'</span><span class="p">:</span><span class="s1">'manager'</span><span class="p">,</span> <span class="s1">'concrete'</span><span class="p">:</span><span class="kc">True</span><span class="p">}</span></pre></div>
</div>
<p>The helper classes <a class="reference internal" href="api.html#sqlalchemy.ext.declarative.AbstractConcreteBase" title="sqlalchemy.ext.declarative.AbstractConcreteBase"><code class="xref py py-class docutils literal notranslate"><span class="pre">AbstractConcreteBase</span></code></a> and <a class="reference internal" href="api.html#sqlalchemy.ext.declarative.ConcreteBase" title="sqlalchemy.ext.declarative.ConcreteBase"><code class="xref py py-class docutils literal notranslate"><span class="pre">ConcreteBase</span></code></a>
provide automation for the above system of creating a polymorphic union.
See the documentation for these helpers as well as the main ORM documentation
on concrete inheritance for details.</p>
<div class="admonition seealso">
<p class="admonition-title">See also</p>
<p><a class="reference internal" href="../../inheritance.html#concrete-inheritance"><span class="std std-ref">Concrete Table Inheritance</span></a></p>
<p><span class="xref std std-ref">inheritance_concrete_helpers</span></p>
</div>
</div>
</div>
</div>
</div>
<div id="docs-bottom-navigation" class="docs-navigation-links, withsidebar">
Previous:
<a href="table_config.html" title="previous chapter">Table Configuration</a>
Next:
<a href="mixins.html" title="next chapter">Mixin and Custom Base Classes</a>
<div id="docs-copyright">
© <a href="../../../copyright.html">Copyright</a> 2007-2019, the SQLAlchemy authors and contributors.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.1.2.
</div>
</div>
</div>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../../../',
VERSION: '1.3.6',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html'
};
</script>
<script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
<!-- begin iterate through sphinx environment script_files -->
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/language_data.js"></script>
<!-- end iterate through sphinx environment script_files -->
<script type="text/javascript" src="../../../_static/detectmobile.js"></script>
<script type="text/javascript" src="../../../_static/init.js"></script>
</body>
</html>