235
240
<p>When using classical mappings, classes must be provided directly without the benefit
236
241
of the “string lookup” system provided by Declarative. SQL expressions are typically
237
specified in terms of the <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> objects, i.e. <tt class="docutils literal"><span class="pre">address.c.id</span></tt> above
242
specified in terms of the <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> objects, i.e. <tt class="docutils literal"><span class="pre">address.c.id</span></tt> above
238
243
for the <tt class="docutils literal"><span class="pre">Address</span></tt> relationship, and not <tt class="docutils literal"><span class="pre">Address.id</span></tt>, as <tt class="docutils literal"><span class="pre">Address</span></tt> may not
239
244
yet be linked to table metadata, nor can we specify a string here.</p>
240
245
<p>Some examples in the documentation still use the classical approach, but note that
241
246
the classical as well as Declarative approaches are <strong>fully interchangeable</strong>. Both
242
systems ultimately create the same configuration, consisting of a <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a>,
247
systems ultimately create the same configuration, consisting of a <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a>,
243
248
user-defined class, linked together with a <a class="reference internal" href="#sqlalchemy.orm.mapper" title="sqlalchemy.orm.mapper"><tt class="xref py py-func docutils literal"><span class="pre">mapper()</span></tt></a>. When we talk about
244
249
“the behavior of <a class="reference internal" href="#sqlalchemy.orm.mapper" title="sqlalchemy.orm.mapper"><tt class="xref py py-func docutils literal"><span class="pre">mapper()</span></tt></a>”, this includes when using the Declarative system
245
250
as well - it’s still used, just behind the scenes.</p>
247
252
<div class="section" id="customizing-column-properties">
248
253
<h2>Customizing Column Properties<a class="headerlink" href="#customizing-column-properties" title="Permalink to this headline">¶</a></h2>
249
254
<p>The default behavior of <a class="reference internal" href="#sqlalchemy.orm.mapper" title="sqlalchemy.orm.mapper"><tt class="xref py py-func docutils literal"><span class="pre">mapper()</span></tt></a> is to assemble all the columns in
250
the mapped <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> into mapped object attributes, each of which are
255
the mapped <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> into mapped object attributes, each of which are
251
256
named according to the name of the column itself (specifically, the <tt class="docutils literal"><span class="pre">key</span></tt>
252
attribute of <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a>). This behavior can be
257
attribute of <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a>). This behavior can be
253
258
modified in several ways.</p>
254
259
<div class="section" id="naming-columns-distinctly-from-attribute-names">
255
<h3>Naming Columns Distinctly from Attribute Names<a class="headerlink" href="#naming-columns-distinctly-from-attribute-names" title="Permalink to this headline">¶</a></h3>
260
<span id="mapper-column-distinct-names"></span><h3>Naming Columns Distinctly from Attribute Names<a class="headerlink" href="#naming-columns-distinctly-from-attribute-names" title="Permalink to this headline">¶</a></h3>
256
261
<p>A mapping by default shares the same name for a
257
<a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> as that of the mapped attribute.
258
The name assigned to the <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> can be different,
262
<a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> as that of the mapped attribute.
263
The name assigned to the <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> can be different,
259
264
as we illustrate here in a Declarative mapping:</p>
260
265
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
261
266
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s">'user'</span>
297
302
<div class="section" id="using-column-property-for-column-level-options">
298
303
<h3>Using column_property for column level options<a class="headerlink" href="#using-column-property-for-column-level-options" title="Permalink to this headline">¶</a></h3>
299
<p>Options can be specified when mapping a <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> using the
304
<p>Options can be specified when mapping a <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> using the
300
305
<a class="reference internal" href="#sqlalchemy.orm.column_property" title="sqlalchemy.orm.column_property"><tt class="xref py py-func docutils literal"><span class="pre">column_property()</span></tt></a> function. This function
301
306
explicitly creates the <a class="reference internal" href="internals.html#sqlalchemy.orm.properties.ColumnProperty" title="sqlalchemy.orm.properties.ColumnProperty"><tt class="xref py py-class docutils literal"><span class="pre">ColumnProperty</span></tt></a> used by the
302
<a class="reference internal" href="#sqlalchemy.orm.mapper" title="sqlalchemy.orm.mapper"><tt class="xref py py-func docutils literal"><span class="pre">mapper()</span></tt></a> to keep track of the <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a>; normally, the
307
<a class="reference internal" href="#sqlalchemy.orm.mapper" title="sqlalchemy.orm.mapper"><tt class="xref py py-func docutils literal"><span class="pre">mapper()</span></tt></a> to keep track of the <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a>; normally, the
303
308
<a class="reference internal" href="#sqlalchemy.orm.mapper" title="sqlalchemy.orm.mapper"><tt class="xref py py-func docutils literal"><span class="pre">mapper()</span></tt></a> creates this automatically. Using <a class="reference internal" href="#sqlalchemy.orm.column_property" title="sqlalchemy.orm.column_property"><tt class="xref py py-func docutils literal"><span class="pre">column_property()</span></tt></a>,
304
we can pass additional arguments about how we’d like the <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a>
309
we can pass additional arguments about how we’d like the <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a>
305
310
to be mapped. Below, we pass an option <tt class="docutils literal"><span class="pre">active_history</span></tt>,
306
311
which specifies that a change to this column’s value should
307
312
result in the former value being loaded first:</p>
455
463
<div class="admonition note">
456
464
<p class="first admonition-title">Note</p>
457
465
<p class="last">insert and update defaults configured on individual
458
<a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> objects, i.e. those described at <a class="reference internal" href="../core/schema.html#metadata-defaults"><em>Column Insert/Update Defaults</em></a>
466
<a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> objects, i.e. those described at <em class="xref std std-ref">metadata_defaults</em>
459
467
including those configured by the <tt class="docutils literal"><span class="pre">default</span></tt>, <tt class="docutils literal"><span class="pre">update</span></tt>,
460
468
<tt class="docutils literal"><span class="pre">server_default</span></tt> and <tt class="docutils literal"><span class="pre">server_onupdate</span></tt> arguments, will continue to
461
function normally even if those <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> objects are not mapped.
469
function normally even if those <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> objects are not mapped.
462
470
This is because in the case of <tt class="docutils literal"><span class="pre">default</span></tt> and <tt class="docutils literal"><span class="pre">update</span></tt>, the
463
<a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> object is still present on the underlying
464
<a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a>, thus allowing the default functions to take place when
471
<a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> object is still present on the underlying
472
<a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a>, thus allowing the default functions to take place when
465
473
the ORM emits an INSERT or UPDATE, and in the case of <tt class="docutils literal"><span class="pre">server_default</span></tt>
466
474
and <tt class="docutils literal"><span class="pre">server_onupdate</span></tt>, the relational database itself maintains these
769
777
<span class="n">correlate_except</span><span class="p">(</span><span class="n">Address</span><span class="p">)</span>
770
778
<span class="p">)</span></pre></div>
772
<p>In the above example, we define a <a class="reference internal" href="../core/expression_api.html#sqlalchemy.sql.expression.select" title="sqlalchemy.sql.expression.select"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> construct like the following:</p>
780
<p>In the above example, we define a <a class="reference internal" href="../core/selectable.html#sqlalchemy.sql.expression.select" title="sqlalchemy.sql.expression.select"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> construct like the following:</p>
773
781
<div class="highlight-python"><div class="highlight"><pre><span class="n">select</span><span class="p">([</span><span class="n">func</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="n">Address</span><span class="o">.</span><span class="n">id</span><span class="p">)])</span><span class="o">.</span>\
774
782
<span class="n">where</span><span class="p">(</span><span class="n">Address</span><span class="o">.</span><span class="n">user_id</span><span class="o">==</span><span class="nb">id</span><span class="p">)</span><span class="o">.</span>\
775
783
<span class="n">correlate_except</span><span class="p">(</span><span class="n">Address</span><span class="p">)</span></pre></div>
777
785
<p>The meaning of the above statement is, select the count of <tt class="docutils literal"><span class="pre">Address.id</span></tt> rows
778
786
where the <tt class="docutils literal"><span class="pre">Address.user_id</span></tt> column is equated to <tt class="docutils literal"><span class="pre">id</span></tt>, which in the context
779
of the <tt class="docutils literal"><span class="pre">User</span></tt> class is the <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> named <tt class="docutils literal"><span class="pre">id</span></tt> (note that <tt class="docutils literal"><span class="pre">id</span></tt> is
787
of the <tt class="docutils literal"><span class="pre">User</span></tt> class is the <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> named <tt class="docutils literal"><span class="pre">id</span></tt> (note that <tt class="docutils literal"><span class="pre">id</span></tt> is
780
788
also the name of a Python built in function, which is not what we want to use
781
789
here - if we were outside of the <tt class="docutils literal"><span class="pre">User</span></tt> class definition, we’d use <tt class="docutils literal"><span class="pre">User.id</span></tt>).</p>
782
790
<p>The <tt class="xref py py-meth docutils literal"><span class="pre">select.correlate_except()</span></tt> directive indicates that each element in the
783
FROM clause of this <a class="reference internal" href="../core/expression_api.html#sqlalchemy.sql.expression.select" title="sqlalchemy.sql.expression.select"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> may be omitted from the FROM list (that is, correlated
791
FROM clause of this <a class="reference internal" href="../core/selectable.html#sqlalchemy.sql.expression.select" title="sqlalchemy.sql.expression.select"><tt class="xref py py-func docutils literal"><span class="pre">select()</span></tt></a> may be omitted from the FROM list (that is, correlated
784
792
to the enclosing SELECT statement against <tt class="docutils literal"><span class="pre">User</span></tt>) except for the one corresponding
785
793
to <tt class="docutils literal"><span class="pre">Address</span></tt>. This isn’t strictly necessary, but prevents <tt class="docutils literal"><span class="pre">Address</span></tt> from
786
794
being inadvertently omitted from the FROM list in the case of a long string
1037
1046
<h3>Synonyms<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
1038
1047
<p>Synonyms are a mapper-level construct that applies expression behavior to a descriptor
1039
1048
based attribute.</p>
1040
<p class="versionchanged">
1041
<span class="versionmodified">Changed in version 0.7: </span>The functionality of synonym is superceded as of 0.7 by hybrid attributes.</p>
1049
<div class="versionchanged">
1050
<p><span>Changed in version 0.7: </span>The functionality of synonym is superceded as of 0.7 by hybrid attributes.</p>
1042
1052
<dl class="function">
1043
1053
<dt id="sqlalchemy.orm.synonym">
1044
1054
<tt class="descclassname">sqlalchemy.orm.</tt><tt class="descname">synonym</tt><big>(</big><em>name</em>, <em>map_column=False</em>, <em>descriptor=None</em>, <em>comparator_factory=None</em>, <em>doc=None</em><big>)</big><a class="headerlink" href="#sqlalchemy.orm.synonym" title="Permalink to this definition">¶</a></dt>
1045
1055
<dd><p>Denote an attribute name as a synonym to a mapped property.</p>
1046
<p class="versionchanged">
1047
<span class="versionmodified">Changed in version 0.7: </span><a class="reference internal" href="#sqlalchemy.orm.synonym" title="sqlalchemy.orm.synonym"><tt class="xref py py-func docutils literal"><span class="pre">synonym()</span></tt></a> is superseded by the <a class="reference internal" href="extensions/hybrid.html#module-sqlalchemy.ext.hybrid" title="sqlalchemy.ext.hybrid"><tt class="xref py py-mod docutils literal"><span class="pre">hybrid</span></tt></a>
1056
<div class="versionchanged">
1057
<p><span>Changed in version 0.7: </span><a class="reference internal" href="#sqlalchemy.orm.synonym" title="sqlalchemy.orm.synonym"><tt class="xref py py-func docutils literal"><span class="pre">synonym()</span></tt></a> is superseded by the <a class="reference internal" href="extensions/hybrid.html#module-sqlalchemy.ext.hybrid" title="sqlalchemy.ext.hybrid"><tt class="xref py py-mod docutils literal"><span class="pre">hybrid</span></tt></a>
1048
1058
extension. See the documentation for hybrids
1049
1059
at <a class="reference internal" href="extensions/hybrid.html"><em>Hybrid Attributes</em></a>.</p>
1050
1061
<p>Used with the <tt class="docutils literal"><span class="pre">properties</span></tt> dictionary sent to
1051
1062
<a class="reference internal" href="#sqlalchemy.orm.mapper" title="sqlalchemy.orm.mapper"><tt class="xref py py-func docutils literal"><span class="pre">mapper()</span></tt></a>:</p>
1052
1063
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">MyClass</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
1396
1411
<h2>Multiple Mappers for One Class<a class="headerlink" href="#multiple-mappers-for-one-class" title="Permalink to this headline">¶</a></h2>
1397
1412
<p>In modern SQLAlchemy, a particular class is only mapped by one <a class="reference internal" href="#sqlalchemy.orm.mapper" title="sqlalchemy.orm.mapper"><tt class="xref py py-func docutils literal"><span class="pre">mapper()</span></tt></a>
1398
1413
at a time. The rationale here is that the <a class="reference internal" href="#sqlalchemy.orm.mapper" title="sqlalchemy.orm.mapper"><tt class="xref py py-func docutils literal"><span class="pre">mapper()</span></tt></a> modifies the class itself, not only
1399
persisting it towards a particular <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a>, but also <em>instrumenting</em>
1414
persisting it towards a particular <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a>, but also <em>instrumenting</em>
1400
1415
attributes upon the class which are structured specifically according to the
1401
1416
table metadata.</p>
1402
1417
<p>One potential use case for another mapper to exist at the same time is if we
1403
wanted to load instances of our class not just from the immediate <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a>
1418
wanted to load instances of our class not just from the immediate <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a>
1404
1419
to which it is mapped, but from another selectable that is a derivation of that
1405
<a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a>. While there technically is a way to create such a <a class="reference internal" href="#sqlalchemy.orm.mapper" title="sqlalchemy.orm.mapper"><tt class="xref py py-func docutils literal"><span class="pre">mapper()</span></tt></a>,
1420
<a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a>. While there technically is a way to create such a <a class="reference internal" href="#sqlalchemy.orm.mapper" title="sqlalchemy.orm.mapper"><tt class="xref py py-func docutils literal"><span class="pre">mapper()</span></tt></a>,
1406
1421
using the <tt class="docutils literal"><span class="pre">non_primary=True</span></tt> option, this approach is virtually never needed.
1407
1422
Instead, we use the functionality of the <a class="reference internal" href="query.html#sqlalchemy.orm.query.Query" title="sqlalchemy.orm.query.Query"><tt class="xref py py-class docutils literal"><span class="pre">Query</span></tt></a> object to achieve this,
1408
1423
using a method such as <a class="reference internal" href="query.html#sqlalchemy.orm.query.Query.select_from" title="sqlalchemy.orm.query.Query.select_from"><tt class="xref py py-meth docutils literal"><span class="pre">Query.select_from()</span></tt></a>
1497
<div class="section" id="configuring-a-version-counter">
1498
<span id="mapper-version-counter"></span><h2>Configuring a Version Counter<a class="headerlink" href="#configuring-a-version-counter" title="Permalink to this headline">¶</a></h2>
1499
<p>The <a class="reference internal" href="#sqlalchemy.orm.mapper.Mapper" title="sqlalchemy.orm.mapper.Mapper"><tt class="xref py py-class docutils literal"><span class="pre">Mapper</span></tt></a> supports management of a <em class="xref std std-term">version id column</em>, which
1500
is a single table column that increments or otherwise updates its value
1501
each time an <tt class="docutils literal"><span class="pre">UPDATE</span></tt> to the mapped table occurs. This value is checked each
1502
time the ORM emits an <tt class="docutils literal"><span class="pre">UPDATE</span></tt> or <tt class="docutils literal"><span class="pre">DELETE</span></tt> against the row to ensure that
1503
the value held in memory matches the database value.</p>
1504
<p>The purpose of this feature is to detect when two concurrent transactions
1505
are modifying the same row at roughly the same time, or alternatively to provide
1506
a guard against the usage of a “stale” row in a system that might be re-using
1507
data from a previous transaction without refreshing (e.g. if one sets <tt class="docutils literal"><span class="pre">expire_on_commit=False</span></tt>
1508
with a <a class="reference internal" href="session.html#sqlalchemy.orm.session.Session" title="sqlalchemy.orm.session.Session"><tt class="xref py py-class docutils literal"><span class="pre">Session</span></tt></a>, it is possible to re-use the data from a previous
1511
<p class="topic-title first">Concurrent transaction updates</p>
1512
<p>When detecting concurrent updates within transactions, it is typically the
1513
case that the database’s transaction isolation level is below the level of
1514
<em class="xref std std-term">repeatable read</em>; otherwise, the transaction will not be exposed
1515
to a new row value created by a concurrent update which conflicts with
1516
the locally updated value. In this case, the SQLAlchemy versioning
1517
feature will typically not be useful for in-transaction conflict detection,
1518
though it still can be used for cross-transaction staleness detection.</p>
1519
<p>The database that enforces repeatable reads will typically either have locked the
1520
target row against a concurrent update, or is employing some form
1521
of multi version concurrency control such that it will emit an error
1522
when the transaction is committed. SQLAlchemy’s version_id_col is an alternative
1523
which allows version tracking to occur for specific tables within a transaction
1524
that otherwise might not have this isolation level set.</p>
1525
<div class="admonition seealso">
1526
<p class="first admonition-title">See also</p>
1527
<p class="last"><a class="reference external" href="http://www.postgresql.org/docs/9.1/static/transaction-iso.html#XACT-REPEATABLE-READ">Repeatable Read Isolation Level</a> - Postgresql’s implementation of repeatable read, including a description of the error condition.</p>
1530
<div class="section" id="simple-version-counting">
1531
<h3>Simple Version Counting<a class="headerlink" href="#simple-version-counting" title="Permalink to this headline">¶</a></h3>
1532
<p>The most straightforward way to track versions is to add an integer column
1533
to the mapped table, then establish it as the <tt class="docutils literal"><span class="pre">version_id_col</span></tt> within the
1535
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
1536
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s">'user'</span>
1538
<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="bp">True</span><span class="p">)</span>
1539
<span class="n">version_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">nullable</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
1540
<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="n">nullable</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
1542
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span>
1543
<span class="s">"version_id_col"</span><span class="p">:</span> <span class="n">version_id</span>
1544
<span class="p">}</span></pre></div>
1546
<p>Above, the <tt class="docutils literal"><span class="pre">User</span></tt> mapping tracks integer versions using the column
1547
<tt class="docutils literal"><span class="pre">version_id</span></tt>. When an object of type <tt class="docutils literal"><span class="pre">User</span></tt> is first flushed, the
1548
<tt class="docutils literal"><span class="pre">version_id</span></tt> column will be given a value of “1”. Then, an UPDATE
1549
of the table later on will always be emitted in a manner similar to the
1551
<div class="highlight-python"><pre>UPDATE user SET version_id=:version_id, name=:name
1552
WHERE user.id = :user_id AND user.version_id = :user_version_id
1553
{"name": "new name", "version_id": 2, "user_id": 1, "user_version_id": 1}</pre>
1555
<p>The above UPDATE statement is updating the row that not only matches
1556
<tt class="docutils literal"><span class="pre">user.id</span> <span class="pre">=</span> <span class="pre">1</span></tt>, it also is requiring that <tt class="docutils literal"><span class="pre">user.version_id</span> <span class="pre">=</span> <span class="pre">1</span></tt>, where “1”
1557
is the last version identifier we’ve been known to use on this object.
1558
If a transaction elsewhere has modifed the row independently, this version id
1559
will no longer match, and the UPDATE statement will report that no rows matched;
1560
this is the condition that SQLAlchemy tests, that exactly one row matched our
1561
UPDATE (or DELETE) statement. If zero rows match, that indicates our version
1562
of the data is stale, and a <tt class="xref py py-class docutils literal"><span class="pre">StaleDataError</span></tt> is raised.</p>
1564
<div class="section" id="custom-version-counters-types">
1565
<span id="custom-version-counter"></span><h3>Custom Version Counters / Types<a class="headerlink" href="#custom-version-counters-types" title="Permalink to this headline">¶</a></h3>
1566
<p>Other kinds of values or counters can be used for versioning. Common types include
1567
dates and GUIDs. When using an alternate type or counter scheme, SQLAlchemy
1568
provides a hook for this scheme using the <tt class="docutils literal"><span class="pre">version_id_generator</span></tt> argument,
1569
which accepts a version generation callable. This callable is passed the value of the current
1570
known version, and is expected to return the subsequent version.</p>
1571
<p>For example, if we wanted to track the versioning of our <tt class="docutils literal"><span class="pre">User</span></tt> class
1572
using a randomly generated GUID, we could do this (note that some backends
1573
support a native GUID type, but we illustrate here using a simple string):</p>
1574
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">uuid</span>
1576
<span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
1577
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s">'user'</span>
1579
<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="bp">True</span><span class="p">)</span>
1580
<span class="n">version_uuid</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">32</span><span class="p">))</span>
1581
<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="n">nullable</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
1583
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span>
1584
<span class="s">'version_id_col'</span><span class="p">:</span><span class="n">version_uuid</span><span class="p">,</span>
1585
<span class="s">'version_id_generator'</span><span class="p">:</span><span class="k">lambda</span> <span class="n">version</span><span class="p">:</span> <span class="n">uuid</span><span class="o">.</span><span class="n">uuid4</span><span class="p">()</span><span class="o">.</span><span class="n">hex</span>
1586
<span class="p">}</span></pre></div>
1588
<p>The persistence engine will call upon <tt class="docutils literal"><span class="pre">uuid.uuid4()</span></tt> each time a
1589
<tt class="docutils literal"><span class="pre">User</span></tt> object is subject to an INSERT or an UPDATE. In this case, our
1590
version generation function can disregard the incoming value of <tt class="docutils literal"><span class="pre">version</span></tt>,
1591
as the <tt class="docutils literal"><span class="pre">uuid4()</span></tt> function
1592
generates identifiers without any prerequisite value. If we were using
1593
a sequential versioning scheme such as numeric or a special character system,
1594
we could make use of the given <tt class="docutils literal"><span class="pre">version</span></tt> in order to help determine the
1595
subsequent value.</p>
1596
<div class="admonition seealso">
1597
<p class="first admonition-title">See also</p>
1598
<p class="last"><a class="reference internal" href="../core/types.html#custom-guid-type"><em>Backend-agnostic GUID Type</em></a></p>
1482
1602
<div class="section" id="class-mapping-api">
1483
1603
<h2>Class Mapping API<a class="headerlink" href="#class-mapping-api" title="Permalink to this headline">¶</a></h2>
1484
1604
<dl class="function">
1531
1651
<li><strong>class_</strong> – The class to be mapped. When using Declarative,
1532
1652
this argument is automatically passed as the declared class
1534
<li><strong>local_table</strong> – The <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> or other selectable
1654
<li><strong>local_table</strong> – The <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> or other selectable
1535
1655
to which the class is mapped. May be <tt class="docutils literal"><span class="pre">None</span></tt> if
1536
1656
this mapper inherits from another mapper using single-table
1537
1657
inheritance. When using Declarative, this argument is
1538
1658
automatically passed by the extension, based on what
1539
1659
is configured via the <tt class="docutils literal"><span class="pre">__table__</span></tt> argument or via the
1540
<a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> produced as a result of the <tt class="docutils literal"><span class="pre">__tablename__</span></tt>
1541
and <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> arguments present.</li>
1660
<a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> produced as a result of the <tt class="docutils literal"><span class="pre">__tablename__</span></tt>
1661
and <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> arguments present.</li>
1542
1662
<li><strong>always_refresh</strong> – If True, all query operations for this mapped
1543
1663
class will overwrite all data within object instances that already
1544
1664
exist within the session, erasing any in-memory changes with
1648
1779
operation for an update. The <a class="reference internal" href="#sqlalchemy.orm.mapper.Mapper" title="sqlalchemy.orm.mapper.Mapper"><tt class="xref py py-class docutils literal"><span class="pre">Mapper</span></tt></a> here will
1649
1780
emit an UPDATE statement for the dependent columns during a
1650
1781
primary key change.</p>
1652
<p><a class="reference internal" href="relationships.html#passive-updates"><em>Mutable Primary Keys / Update Cascades</em></a> - description of a similar feature as
1782
<div class="admonition seealso">
1783
<p class="first admonition-title">See also</p>
1784
<p class="last"><a class="reference internal" href="relationships.html#passive-updates"><em>Mutable Primary Keys / Update Cascades</em></a> - description of a similar feature as
1653
1785
used with <a class="reference internal" href="relationships.html#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a></p>
1655
1788
<li><strong>polymorphic_on</strong> – <p>Specifies the column, attribute, or
1656
1789
SQL expression used to determine the target class for an
1657
1790
incoming row, when inheriting classes are present.</p>
1658
<p>This value is commonly a <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> object that’s
1659
present in the mapped <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a>:</p>
1791
<p>This value is commonly a <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> object that’s
1792
present in the mapped <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a>:</p>
1660
1793
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Employee</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
1661
1794
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s">'employee'</span>
1744
1880
be used for the newly reconstructed object.</li>
1745
1881
<li><strong>properties</strong> – A dictionary mapping the string names of object
1746
1882
attributes to <a class="reference internal" href="internals.html#sqlalchemy.orm.interfaces.MapperProperty" title="sqlalchemy.orm.interfaces.MapperProperty"><tt class="xref py py-class docutils literal"><span class="pre">MapperProperty</span></tt></a> instances, which define the
1747
persistence behavior of that attribute. Note that <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a>
1883
persistence behavior of that attribute. Note that <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a>
1748
1884
objects present in
1749
the mapped <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> are automatically placed into
1885
the mapped <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> are automatically placed into
1750
1886
<tt class="docutils literal"><span class="pre">ColumnProperty</span></tt> instances upon mapping, unless overridden.
1751
1887
When using Declarative, this argument is passed automatically,
1752
1888
based on all those <a class="reference internal" href="internals.html#sqlalchemy.orm.interfaces.MapperProperty" title="sqlalchemy.orm.interfaces.MapperProperty"><tt class="xref py py-class docutils literal"><span class="pre">MapperProperty</span></tt></a> instances declared
1753
1889
in the declared class body.</li>
1754
<li><strong>primary_key</strong> – A list of <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> objects which define the
1890
<li><strong>primary_key</strong> – A list of <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> objects which define the
1755
1891
primary key to be used against this mapper’s selectable unit.
1756
1892
This is normally simply the primary key of the <tt class="docutils literal"><span class="pre">local_table</span></tt>, but
1757
1893
can be overridden here.</li>
1758
<li><strong>version_id_col</strong> – A <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a>
1759
that will be used to keep a running version id of mapped entities
1760
in the database. This is used during save operations to ensure that
1761
no other thread or process has updated the instance during the
1762
lifetime of the entity, else a
1894
<li><strong>version_id_col</strong> – <p>A <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a>
1895
that will be used to keep a running version id of rows
1896
in the table. This is used to detect concurrent updates or
1897
the presence of stale data in a flush. The methodology is to
1898
detect if an UPDATE statement does not match the last known
1763
1900
<a class="reference internal" href="exceptions.html#sqlalchemy.orm.exc.StaleDataError" title="sqlalchemy.orm.exc.StaleDataError"><tt class="xref py py-class docutils literal"><span class="pre">StaleDataError</span></tt></a> exception is
1764
thrown. By default the column must be of <a class="reference internal" href="../core/types.html#sqlalchemy.types.Integer" title="sqlalchemy.types.Integer"><tt class="xref py py-class docutils literal"><span class="pre">Integer</span></tt></a> type,
1765
unless <tt class="docutils literal"><span class="pre">version_id_generator</span></tt> specifies a new generation
1767
<li><strong>version_id_generator</strong> – <p>A callable which defines the algorithm
1768
used to generate new version ids. Defaults to an integer
1769
generator. Can be replaced with one that generates timestamps,
1770
uuids, etc. e.g.:</p>
1771
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">uuid</span>
1773
<span class="k">class</span> <span class="nc">MyClass</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
1774
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s">'mytable'</span>
1775
<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="bp">True</span><span class="p">)</span>
1776
<span class="n">version_uuid</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">32</span><span class="p">))</span>
1778
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span>
1779
<span class="s">'version_id_col'</span><span class="p">:</span><span class="n">version_uuid</span><span class="p">,</span>
1780
<span class="s">'version_id_generator'</span><span class="p">:</span><span class="k">lambda</span> <span class="n">version</span><span class="p">:</span><span class="n">uuid</span><span class="o">.</span><span class="n">uuid4</span><span class="p">()</span><span class="o">.</span><span class="n">hex</span>
1781
<span class="p">}</span></pre></div>
1783
<p>The callable receives the current version identifier as its
1784
single argument.</p>
1902
By default, the column must be of <a class="reference internal" href="../core/types.html#sqlalchemy.types.Integer" title="sqlalchemy.types.Integer"><tt class="xref py py-class docutils literal"><span class="pre">Integer</span></tt></a> type,
1903
unless <tt class="docutils literal"><span class="pre">version_id_generator</span></tt> specifies an alternative version
1905
<div class="admonition seealso">
1906
<p class="first admonition-title">See also</p>
1907
<p class="last"><a class="reference internal" href="#mapper-version-counter"><em>Configuring a Version Counter</em></a> - discussion of version counting
1911
<li><strong>version_id_generator</strong> – <p>Define how new version ids should
1912
be generated. Defaults to <tt class="docutils literal"><span class="pre">None</span></tt>, which indicates that
1913
a simple integer counting scheme be employed. To provide a custom
1914
versioning scheme, provide a callable function of the form:</p>
1915
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">generate_version</span><span class="p">(</span><span class="n">version</span><span class="p">):</span>
1916
<span class="k">return</span> <span class="n">next_version</span></pre></div>
1918
<div class="admonition seealso">
1919
<p class="first admonition-title">See also</p>
1920
<p class="last"><a class="reference internal" href="#custom-version-counter"><em>Custom Version Counters / Types</em></a></p>
1786
1923
<li><strong>with_polymorphic</strong> – <p>A tuple in the form <tt class="docutils literal"><span class="pre">(<classes>,</span>
1787
1924
<span class="pre"><selectable>)</span></tt> indicating the default style of “polymorphic”
2102
2240
<dl class="attribute">
2103
2241
<dt id="sqlalchemy.orm.mapper.Mapper.columns">
2104
2242
<tt class="descname">columns</tt><em class="property"> = None</em><a class="headerlink" href="#sqlalchemy.orm.mapper.Mapper.columns" title="Permalink to this definition">¶</a></dt>
2105
<dd><p>A collection of <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> or other scalar expression
2243
<dd><p>A collection of <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> or other scalar expression
2106
2244
objects maintained by this <a class="reference internal" href="#sqlalchemy.orm.mapper.Mapper" title="sqlalchemy.orm.mapper.Mapper"><tt class="xref py py-class docutils literal"><span class="pre">Mapper</span></tt></a>.</p>
2107
2245
<p>The collection behaves the same as that of the <tt class="docutils literal"><span class="pre">c</span></tt> attribute on
2108
any <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> object, except that only those columns included in
2246
any <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> object, except that only those columns included in
2109
2247
this mapping are present, and are keyed based on the attribute name
2110
2248
defined in the mapping, not necessarily the <tt class="docutils literal"><span class="pre">key</span></tt> attribute of the
2111
<a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> itself. Additionally, scalar expressions mapped
2249
<a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> itself. Additionally, scalar expressions mapped
2112
2250
by <a class="reference internal" href="#sqlalchemy.orm.column_property" title="sqlalchemy.orm.column_property"><tt class="xref py py-func docutils literal"><span class="pre">column_property()</span></tt></a> are also present here.</p>
2113
2251
<p>This is a <em>read only</em> attribute determined during mapper construction.
2114
2252
Behavior is undefined if directly modified.</p>
2265
2405
<dl class="attribute">
2266
2406
<dt id="sqlalchemy.orm.mapper.Mapper.mapped_table">
2267
2407
<tt class="descname">mapped_table</tt><em class="property"> = None</em><a class="headerlink" href="#sqlalchemy.orm.mapper.Mapper.mapped_table" title="Permalink to this definition">¶</a></dt>
2268
<dd><p>The <a class="reference internal" href="../core/expression_api.html#sqlalchemy.sql.expression.Selectable" title="sqlalchemy.sql.expression.Selectable"><tt class="xref py py-class docutils literal"><span class="pre">Selectable</span></tt></a> to which this <a class="reference internal" href="#sqlalchemy.orm.mapper.Mapper" title="sqlalchemy.orm.mapper.Mapper"><tt class="xref py py-class docutils literal"><span class="pre">Mapper</span></tt></a> is mapped.</p>
2269
<p>Typically an instance of <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a>, <a class="reference internal" href="../core/expression_api.html#sqlalchemy.sql.expression.Join" title="sqlalchemy.sql.expression.Join"><tt class="xref py py-class docutils literal"><span class="pre">Join</span></tt></a>, or
2270
<a class="reference internal" href="../core/expression_api.html#sqlalchemy.sql.expression.Alias" title="sqlalchemy.sql.expression.Alias"><tt class="xref py py-class docutils literal"><span class="pre">Alias</span></tt></a>.</p>
2408
<dd><p>The <a class="reference internal" href="../core/selectable.html#sqlalchemy.sql.expression.Selectable" title="sqlalchemy.sql.expression.Selectable"><tt class="xref py py-class docutils literal"><span class="pre">Selectable</span></tt></a> to which this <a class="reference internal" href="#sqlalchemy.orm.mapper.Mapper" title="sqlalchemy.orm.mapper.Mapper"><tt class="xref py py-class docutils literal"><span class="pre">Mapper</span></tt></a> is mapped.</p>
2409
<p>Typically an instance of <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a>, <a class="reference internal" href="../core/selectable.html#sqlalchemy.sql.expression.Join" title="sqlalchemy.sql.expression.Join"><tt class="xref py py-class docutils literal"><span class="pre">Join</span></tt></a>, or
2410
<a class="reference internal" href="../core/selectable.html#sqlalchemy.sql.expression.Alias" title="sqlalchemy.sql.expression.Alias"><tt class="xref py py-class docutils literal"><span class="pre">Alias</span></tt></a>.</p>
2271
2411
<p>The “mapped” table is the selectable that
2272
2412
the mapper selects from during queries. For non-inheriting
2273
2413
mappers, the mapped table is the same as the “local” table.
2274
2414
For joined-table inheritance mappers, mapped_table references the
2275
full <a class="reference internal" href="../core/expression_api.html#sqlalchemy.sql.expression.Join" title="sqlalchemy.sql.expression.Join"><tt class="xref py py-class docutils literal"><span class="pre">Join</span></tt></a> representing full rows for this particular
2415
full <a class="reference internal" href="../core/selectable.html#sqlalchemy.sql.expression.Join" title="sqlalchemy.sql.expression.Join"><tt class="xref py py-class docutils literal"><span class="pre">Join</span></tt></a> representing full rows for this particular
2276
2416
subclass. For single-table inheritance mappers, mapped_table
2277
2417
references the base table.</p>
2278
2418
<p>See also <a class="reference internal" href="#sqlalchemy.orm.mapper.Mapper.local_table" title="sqlalchemy.orm.mapper.Mapper.local_table"><tt class="xref py py-attr docutils literal"><span class="pre">local_table</span></tt></a>.</p>
2348
2488
<dl class="attribute">
2349
2489
<dt id="sqlalchemy.orm.mapper.Mapper.primary_key">
2350
2490
<tt class="descname">primary_key</tt><em class="property"> = None</em><a class="headerlink" href="#sqlalchemy.orm.mapper.Mapper.primary_key" title="Permalink to this definition">¶</a></dt>
2351
<dd><p>An iterable containing the collection of <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> objects
2491
<dd><p>An iterable containing the collection of <a class="reference internal" href="../core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> objects
2352
2492
which comprise the ‘primary key’ of the mapped table, from the
2353
2493
perspective of this <a class="reference internal" href="#sqlalchemy.orm.mapper.Mapper" title="sqlalchemy.orm.mapper.Mapper"><tt class="xref py py-class docutils literal"><span class="pre">Mapper</span></tt></a>.</p>
2354
2494
<p>This list is against the selectable in <a class="reference internal" href="#sqlalchemy.orm.mapper.Mapper.mapped_table" title="sqlalchemy.orm.mapper.Mapper.mapped_table"><tt class="xref py py-attr docutils literal"><span class="pre">mapped_table</span></tt></a>. In
2355
2495
the case of inheriting mappers, some columns may be managed by a
2356
superclass mapper. For example, in the case of a <a class="reference internal" href="../core/expression_api.html#sqlalchemy.sql.expression.Join" title="sqlalchemy.sql.expression.Join"><tt class="xref py py-class docutils literal"><span class="pre">Join</span></tt></a>, the
2496
superclass mapper. For example, in the case of a <a class="reference internal" href="../core/selectable.html#sqlalchemy.sql.expression.Join" title="sqlalchemy.sql.expression.Join"><tt class="xref py py-class docutils literal"><span class="pre">Join</span></tt></a>, the
2357
2497
primary key is determined by all of the primary key columns across all
2358
tables referenced by the <a class="reference internal" href="../core/expression_api.html#sqlalchemy.sql.expression.Join" title="sqlalchemy.sql.expression.Join"><tt class="xref py py-class docutils literal"><span class="pre">Join</span></tt></a>.</p>
2498
tables referenced by the <a class="reference internal" href="../core/selectable.html#sqlalchemy.sql.expression.Join" title="sqlalchemy.sql.expression.Join"><tt class="xref py py-class docutils literal"><span class="pre">Join</span></tt></a>.</p>
2359
2499
<p>The list is also not necessarily the same as the primary key column
2360
2500
collection associated with the underlying tables; the <a class="reference internal" href="#sqlalchemy.orm.mapper.Mapper" title="sqlalchemy.orm.mapper.Mapper"><tt class="xref py py-class docutils literal"><span class="pre">Mapper</span></tt></a>
2361
2501
features a <tt class="docutils literal"><span class="pre">primary_key</span></tt> argument that can override what the