~ubuntu-branches/debian/jessie/sqlalchemy/jessie

« back to all changes in this revision

Viewing changes to doc/orm/extensions/mutable.html

  • Committer: Package Import Robot
  • Author(s): Piotr Ożarowski, Jakub Wilk, Piotr Ożarowski
  • Date: 2013-07-06 20:53:52 UTC
  • mfrom: (1.4.23) (16.1.17 experimental)
  • Revision ID: package-import@ubuntu.com-20130706205352-ryppl1eto3illd79
Tags: 0.8.2-1
[ Jakub Wilk ]
* Use canonical URIs for Vcs-* fields.

[ Piotr Ożarowski ]
* New upstream release
* Upload to unstable
* Build depend on python3-all instead of -dev, extensions are not built for
  Python 3.X 

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
    
11
11
                Mutation Tracking
12
12
             — 
13
 
    SQLAlchemy 0.7 Documentation
 
13
    SQLAlchemy 0.8 Documentation
14
14
 
15
15
        </title>
16
16
        
20
20
    <script type="text/javascript">
21
21
      var DOCUMENTATION_OPTIONS = {
22
22
          URL_ROOT:    '../../',
23
 
          VERSION:     '0.7.9',
 
23
          VERSION:     '0.8.2',
24
24
          COLLAPSE_MODINDEX: false,
25
25
          FILE_SUFFIX: '.html'
26
26
      };
32
32
    <link rel="index" title="Index" href="../../genindex.html" />
33
33
    <link rel="search" title="Search" href="../../search.html" />
34
34
        <link rel="copyright" title="Copyright" href="../../copyright.html" />
35
 
    <link rel="top" title="SQLAlchemy 0.7 Documentation" href="../../index.html" />
 
35
    <link rel="top" title="SQLAlchemy 0.8 Documentation" href="../../index.html" />
36
36
        <link rel="up" title="ORM Extensions" href="index.html" />
37
37
        <link rel="next" title="Ordering List" href="orderinglist.html" />
38
38
        <link rel="prev" title="Declarative" href="declarative.html" />
55
55
 
56
56
 
57
57
<div id="docs-header">
58
 
    <h1>SQLAlchemy 0.7 Documentation</h1>
 
58
    <h1>SQLAlchemy 0.8 Documentation</h1>
59
59
 
60
60
    <div id="docs-search">
61
61
    Search:
67
67
    </div>
68
68
 
69
69
    <div id="docs-version-header">
70
 
        Release: <span class="version-num">0.7.9</span> | Release Date: October 1, 2012
 
70
        Release: <span class="version-num">0.8.2</span> | Release Date: July 3, 2013
71
71
 
72
72
 
73
73
    </div>
93
93
    </div>
94
94
 
95
95
    <div id="docs-navigation-banner">
96
 
        <a href="../../index.html">SQLAlchemy 0.7 Documentation</a>
 
96
        <a href="../../index.html">SQLAlchemy 0.8 Documentation</a>
97
97
                » <a href="../index.html" title="SQLAlchemy ORM">SQLAlchemy ORM</a>
98
98
                » <a href="index.html" title="ORM Extensions">ORM Extensions</a>
99
99
        » 
120
120
</ul>
121
121
</li>
122
122
<li><a class="reference internal" href="#establishing-mutability-on-composites">Establishing Mutability on Composites</a><ul>
 
123
<li><a class="reference internal" href="#coercing-mutable-composites">Coercing Mutable Composites</a></li>
123
124
<li><a class="reference internal" href="#id1">Supporting Pickling</a></li>
124
125
</ul>
125
126
</li>
156
157
<span id="mutation-tracking"></span><span id="mutable-toplevel"></span><h1>Mutation Tracking<a class="headerlink" href="#module-sqlalchemy.ext.mutable" title="Permalink to this headline">¶</a></h1>
157
158
<p>Provide support for tracking of in-place changes to scalar values,
158
159
which are propagated into ORM change events on owning parent objects.</p>
159
 
<p>The <a class="reference internal" href="#module-sqlalchemy.ext.mutable" title="sqlalchemy.ext.mutable"><tt class="xref py py-mod docutils literal"><span class="pre">sqlalchemy.ext.mutable</span></tt></a> extension replaces SQLAlchemy&#8217;s legacy approach to in-place
160
 
mutations of scalar values, established by the <a class="reference internal" href="../../core/types.html#sqlalchemy.types.MutableType" title="sqlalchemy.types.MutableType"><tt class="xref py py-class docutils literal"><span class="pre">types.MutableType</span></tt></a>
161
 
class as well as the <tt class="docutils literal"><span class="pre">mutable=True</span></tt> type flag, with a system that allows
162
 
change events to be propagated from the value to the owning parent, thereby
163
 
removing the need for the ORM to maintain copies of values as well as the very
164
 
expensive requirement of scanning through all &#8220;mutable&#8221; values on each flush
165
 
call, looking for changes.</p>
 
160
<p>The <a class="reference internal" href="#module-sqlalchemy.ext.mutable" title="sqlalchemy.ext.mutable"><tt class="xref py py-mod docutils literal"><span class="pre">sqlalchemy.ext.mutable</span></tt></a> extension replaces SQLAlchemy&#8217;s legacy
 
161
approach to in-place mutations of scalar values, established by the
 
162
<tt class="xref py py-class docutils literal"><span class="pre">types.MutableType</span></tt> class as well as the <tt class="docutils literal"><span class="pre">mutable=True</span></tt> type flag,
 
163
with a system that allows change events to be propagated from the value to
 
164
the owning parent, thereby removing the need for the ORM to maintain copies
 
165
of values as well as the very expensive requirement of scanning through all
 
166
&#8220;mutable&#8221; values on each flush call, looking for changes.</p>
166
167
<div class="section" id="establishing-mutability-on-scalar-column-values">
167
168
<span id="mutable-scalars"></span><h2>Establishing Mutability on Scalar Column Values<a class="headerlink" href="#establishing-mutability-on-scalar-column-values" title="Permalink to this headline">¶</a></h2>
168
169
<p>A typical example of a &#8220;mutable&#8221; structure is a Python dictionary.
187
188
            <span class="n">value</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
188
189
        <span class="k">return</span> <span class="n">value</span></pre></div>
189
190
</div>
190
 
<p>The usage of <tt class="docutils literal"><span class="pre">json</span></tt> is only for the purposes of example. The <a class="reference internal" href="#module-sqlalchemy.ext.mutable" title="sqlalchemy.ext.mutable"><tt class="xref py py-mod docutils literal"><span class="pre">sqlalchemy.ext.mutable</span></tt></a>
191
 
extension can be used
 
191
<p>The usage of <tt class="docutils literal"><span class="pre">json</span></tt> is only for the purposes of example. The
 
192
<a class="reference internal" href="#module-sqlalchemy.ext.mutable" title="sqlalchemy.ext.mutable"><tt class="xref py py-mod docutils literal"><span class="pre">sqlalchemy.ext.mutable</span></tt></a> extension can be used
192
193
with any type whose target Python type may be mutable, including
193
194
<a class="reference internal" href="../../core/types.html#sqlalchemy.types.PickleType" title="sqlalchemy.types.PickleType"><tt class="xref py py-class docutils literal"><span class="pre">PickleType</span></tt></a>, <a class="reference internal" href="../../dialects/postgresql.html#sqlalchemy.dialects.postgresql.ARRAY" title="sqlalchemy.dialects.postgresql.ARRAY"><tt class="xref py py-class docutils literal"><span class="pre">postgresql.ARRAY</span></tt></a>, etc.</p>
194
195
<p>When using the <a class="reference internal" href="#module-sqlalchemy.ext.mutable" title="sqlalchemy.ext.mutable"><tt class="xref py py-mod docutils literal"><span class="pre">sqlalchemy.ext.mutable</span></tt></a> extension, the value itself
195
 
tracks all parents which reference it.  Here we will replace the usage
196
 
of plain Python dictionaries with a dict subclass that implements
197
 
the <a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable" title="sqlalchemy.ext.mutable.Mutable"><tt class="xref py py-class docutils literal"><span class="pre">Mutable</span></tt></a> mixin:</p>
 
196
tracks all parents which reference it.  Below, we illustrate the a simple
 
197
version of the <a class="reference internal" href="#sqlalchemy.ext.mutable.MutableDict" title="sqlalchemy.ext.mutable.MutableDict"><tt class="xref py py-class docutils literal"><span class="pre">MutableDict</span></tt></a> dictionary object, which applies
 
198
the <a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable" title="sqlalchemy.ext.mutable.Mutable"><tt class="xref py py-class docutils literal"><span class="pre">Mutable</span></tt></a> mixin to a plain Python dictionary:</p>
198
199
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">collections</span>
199
200
<span class="kn">from</span> <span class="nn">sqlalchemy.ext.mutable</span> <span class="kn">import</span> <span class="n">Mutable</span>
200
201
 
201
 
<span class="k">class</span> <span class="nc">MutationDict</span><span class="p">(</span><span class="n">Mutable</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
 
202
<span class="k">class</span> <span class="nc">MutableDict</span><span class="p">(</span><span class="n">Mutable</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
202
203
    <span class="nd">@classmethod</span>
203
204
    <span class="k">def</span> <span class="nf">coerce</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
204
 
        <span class="s">&quot;Convert plain dictionaries to MutationDict.&quot;</span>
 
205
        <span class="s">&quot;Convert plain dictionaries to MutableDict.&quot;</span>
205
206
 
206
 
        <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">MutationDict</span><span class="p">):</span>
 
207
        <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">MutableDict</span><span class="p">):</span>
207
208
            <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
208
 
                <span class="k">return</span> <span class="n">MutationDict</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
 
209
                <span class="k">return</span> <span class="n">MutableDict</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
209
210
 
210
211
            <span class="c"># this call will raise ValueError</span>
211
212
            <span class="k">return</span> <span class="n">Mutable</span><span class="o">.</span><span class="n">coerce</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
226
227
</div>
227
228
<p>The above dictionary class takes the approach of subclassing the Python
228
229
built-in <tt class="docutils literal"><span class="pre">dict</span></tt> to produce a dict
229
 
subclass which routes all mutation events through <tt class="docutils literal"><span class="pre">__setitem__</span></tt>. There are
230
 
many variants on this approach, such as subclassing <tt class="docutils literal"><span class="pre">UserDict.UserDict</span></tt>,
231
 
the newer <tt class="docutils literal"><span class="pre">collections.MutableMapping</span></tt>,  etc. The part that&#8217;s important to this
232
 
example is that the <a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable.changed" title="sqlalchemy.ext.mutable.Mutable.changed"><tt class="xref py py-meth docutils literal"><span class="pre">Mutable.changed()</span></tt></a> method is called whenever an in-place change to the
233
 
datastructure takes place.</p>
 
230
subclass which routes all mutation events through <tt class="docutils literal"><span class="pre">__setitem__</span></tt>.  There are
 
231
variants on this approach, such as subclassing <tt class="docutils literal"><span class="pre">UserDict.UserDict</span></tt> or
 
232
<tt class="docutils literal"><span class="pre">collections.MutableMapping</span></tt>; the part that&#8217;s important to this example is
 
233
that the <a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable.changed" title="sqlalchemy.ext.mutable.Mutable.changed"><tt class="xref py py-meth docutils literal"><span class="pre">Mutable.changed()</span></tt></a> method is called whenever an in-place
 
234
change to the datastructure takes place.</p>
234
235
<p>We also redefine the <tt class="xref py py-meth docutils literal"><span class="pre">Mutable.coerce()</span></tt> method which will be used to
235
 
convert any values that are not instances of <tt class="docutils literal"><span class="pre">MutationDict</span></tt>, such
 
236
convert any values that are not instances of <tt class="docutils literal"><span class="pre">MutableDict</span></tt>, such
236
237
as the plain dictionaries returned by the <tt class="docutils literal"><span class="pre">json</span></tt> module, into the
237
 
appropriate type.  Defining this method is optional; we could just as well created our
238
 
<tt class="docutils literal"><span class="pre">JSONEncodedDict</span></tt> such that it always returns an instance of <tt class="docutils literal"><span class="pre">MutationDict</span></tt>,
239
 
and additionally ensured that all calling code uses <tt class="docutils literal"><span class="pre">MutationDict</span></tt>
240
 
explicitly.  When <tt class="xref py py-meth docutils literal"><span class="pre">Mutable.coerce()</span></tt> is not overridden, any values
241
 
applied to a parent object which are not instances of the mutable type
242
 
will raise a <tt class="docutils literal"><span class="pre">ValueError</span></tt>.</p>
243
 
<p>Our new <tt class="docutils literal"><span class="pre">MutationDict</span></tt> type offers a class method
 
238
appropriate type.  Defining this method is optional; we could just as well
 
239
created our <tt class="docutils literal"><span class="pre">JSONEncodedDict</span></tt> such that it always returns an instance
 
240
of <tt class="docutils literal"><span class="pre">MutableDict</span></tt>, and additionally ensured that all calling code
 
241
uses <tt class="docutils literal"><span class="pre">MutableDict</span></tt> explicitly.  When <tt class="xref py py-meth docutils literal"><span class="pre">Mutable.coerce()</span></tt> is not
 
242
overridden, any values applied to a parent object which are not instances
 
243
of the mutable type will raise a <tt class="docutils literal"><span class="pre">ValueError</span></tt>.</p>
 
244
<p>Our new <tt class="docutils literal"><span class="pre">MutableDict</span></tt> type offers a class method
244
245
<a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable.as_mutable" title="sqlalchemy.ext.mutable.Mutable.as_mutable"><tt class="xref py py-meth docutils literal"><span class="pre">as_mutable()</span></tt></a> which we can use within column metadata
245
246
to associate with types. This method grabs the given type object or
246
247
class and associates a listener that will detect all future mappings
250
251
 
251
252
<span class="n">my_data</span> <span class="o">=</span> <span class="n">Table</span><span class="p">(</span><span class="s">&#39;my_data&#39;</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span>
252
253
    <span class="n">Column</span><span class="p">(</span><span class="s">&#39;id&#39;</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>
253
 
    <span class="n">Column</span><span class="p">(</span><span class="s">&#39;data&#39;</span><span class="p">,</span> <span class="n">MutationDict</span><span class="o">.</span><span class="n">as_mutable</span><span class="p">(</span><span class="n">JSONEncodedDict</span><span class="p">))</span>
 
254
    <span class="n">Column</span><span class="p">(</span><span class="s">&#39;data&#39;</span><span class="p">,</span> <span class="n">MutableDict</span><span class="o">.</span><span class="n">as_mutable</span><span class="p">(</span><span class="n">JSONEncodedDict</span><span class="p">))</span>
254
255
<span class="p">)</span></pre></div>
255
256
</div>
256
257
<p>Above, <a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable.as_mutable" title="sqlalchemy.ext.mutable.Mutable.as_mutable"><tt class="xref py py-meth docutils literal"><span class="pre">as_mutable()</span></tt></a> returns an instance of <tt class="docutils literal"><span class="pre">JSONEncodedDict</span></tt>
275
276
<span class="k">class</span> <span class="nc">MyDataClass</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
276
277
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;my_data&#39;</span>
277
278
    <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>
278
 
    <span class="n">data</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">MutationDict</span><span class="o">.</span><span class="n">as_mutable</span><span class="p">(</span><span class="n">JSONEncodedDict</span><span class="p">))</span></pre></div>
 
279
    <span class="n">data</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">MutableDict</span><span class="o">.</span><span class="n">as_mutable</span><span class="p">(</span><span class="n">JSONEncodedDict</span><span class="p">))</span></pre></div>
279
280
</div>
280
281
<p>Any in-place changes to the <tt class="docutils literal"><span class="pre">MyDataClass.data</span></tt> member
281
282
will flag the attribute as &#8220;dirty&#8221; on the parent object:</p>
290
291
<span class="gp">&gt;&gt;&gt; </span><span class="k">assert</span> <span class="n">m1</span> <span class="ow">in</span> <span class="n">sess</span><span class="o">.</span><span class="n">dirty</span>
291
292
<span class="go">True</span></pre></div>
292
293
</div>
293
 
<p>The <tt class="docutils literal"><span class="pre">MutationDict</span></tt> can be associated with all future instances
294
 
of <tt class="docutils literal"><span class="pre">JSONEncodedDict</span></tt> in one step, using <a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable.associate_with" title="sqlalchemy.ext.mutable.Mutable.associate_with"><tt class="xref py py-meth docutils literal"><span class="pre">associate_with()</span></tt></a>.  This
295
 
is similar to <a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable.as_mutable" title="sqlalchemy.ext.mutable.Mutable.as_mutable"><tt class="xref py py-meth docutils literal"><span class="pre">as_mutable()</span></tt></a> except it will intercept
296
 
all occurrences of <tt class="docutils literal"><span class="pre">MutationDict</span></tt> in all mappings unconditionally, without
 
294
<p>The <tt class="docutils literal"><span class="pre">MutableDict</span></tt> can be associated with all future instances
 
295
of <tt class="docutils literal"><span class="pre">JSONEncodedDict</span></tt> in one step, using
 
296
<a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable.associate_with" title="sqlalchemy.ext.mutable.Mutable.associate_with"><tt class="xref py py-meth docutils literal"><span class="pre">associate_with()</span></tt></a>.  This is similar to
 
297
<a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable.as_mutable" title="sqlalchemy.ext.mutable.Mutable.as_mutable"><tt class="xref py py-meth docutils literal"><span class="pre">as_mutable()</span></tt></a> except it will intercept all occurrences
 
298
of <tt class="docutils literal"><span class="pre">MutableDict</span></tt> in all mappings unconditionally, without
297
299
the need to declare it individually:</p>
298
 
<div class="highlight-python"><div class="highlight"><pre><span class="n">MutationDict</span><span class="o">.</span><span class="n">associate_with</span><span class="p">(</span><span class="n">JSONEncodedDict</span><span class="p">)</span>
 
300
<div class="highlight-python"><div class="highlight"><pre><span class="n">MutableDict</span><span class="o">.</span><span class="n">associate_with</span><span class="p">(</span><span class="n">JSONEncodedDict</span><span class="p">)</span>
299
301
 
300
302
<span class="k">class</span> <span class="nc">MyDataClass</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
301
303
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;my_data&#39;</span>
323
325
</div>
324
326
<p>With our dictionary example, we need to return the contents of the dict itself
325
327
(and also restore them on __setstate__):</p>
326
 
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">MutationDict</span><span class="p">(</span><span class="n">Mutable</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
 
328
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">MutableDict</span><span class="p">(</span><span class="n">Mutable</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
327
329
    <span class="c"># ....</span>
328
330
 
329
331
    <span class="k">def</span> <span class="nf">__getstate__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
424
426
<span class="gp">&gt;&gt;&gt; </span><span class="k">assert</span> <span class="n">v1</span> <span class="ow">in</span> <span class="n">sess</span><span class="o">.</span><span class="n">dirty</span>
425
427
<span class="go">True</span></pre></div>
426
428
</div>
 
429
<div class="section" id="coercing-mutable-composites">
 
430
<h3>Coercing Mutable Composites<a class="headerlink" href="#coercing-mutable-composites" title="Permalink to this headline">¶</a></h3>
 
431
<p>The <a class="reference internal" href="#sqlalchemy.ext.mutable.MutableBase.coerce" title="sqlalchemy.ext.mutable.MutableBase.coerce"><tt class="xref py py-meth docutils literal"><span class="pre">MutableBase.coerce()</span></tt></a> method is also supported on composite types.
 
432
In the case of <a class="reference internal" href="#sqlalchemy.ext.mutable.MutableComposite" title="sqlalchemy.ext.mutable.MutableComposite"><tt class="xref py py-class docutils literal"><span class="pre">MutableComposite</span></tt></a>, the <a class="reference internal" href="#sqlalchemy.ext.mutable.MutableBase.coerce" title="sqlalchemy.ext.mutable.MutableBase.coerce"><tt class="xref py py-meth docutils literal"><span class="pre">MutableBase.coerce()</span></tt></a>
 
433
method is only called for attribute set operations, not load operations.
 
434
Overriding the <a class="reference internal" href="#sqlalchemy.ext.mutable.MutableBase.coerce" title="sqlalchemy.ext.mutable.MutableBase.coerce"><tt class="xref py py-meth docutils literal"><span class="pre">MutableBase.coerce()</span></tt></a> method is essentially equivalent
 
435
to using a <a class="reference internal" href="../mapper_config.html#sqlalchemy.orm.validates" title="sqlalchemy.orm.validates"><tt class="xref py py-func docutils literal"><span class="pre">validates()</span></tt></a> validation routine for all attributes which
 
436
make use of the custom composite type:</p>
 
437
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Point</span><span class="p">(</span><span class="n">MutableComposite</span><span class="p">):</span>
 
438
    <span class="c"># other Point methods</span>
 
439
    <span class="c"># ...</span>
 
440
 
 
441
    <span class="k">def</span> <span class="nf">coerce</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
 
442
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
 
443
            <span class="n">value</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="o">*</span><span class="n">value</span><span class="p">)</span>
 
444
        <span class="k">elif</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">Point</span><span class="p">):</span>
 
445
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s">&quot;tuple or Point expected&quot;</span><span class="p">)</span>
 
446
        <span class="k">return</span> <span class="n">value</span></pre></div>
 
447
</div>
 
448
<p class="versionadded">
 
449
<span class="versionmodified">New in version 0.7.10,0.8.0b2: </span>Support for the <a class="reference internal" href="#sqlalchemy.ext.mutable.MutableBase.coerce" title="sqlalchemy.ext.mutable.MutableBase.coerce"><tt class="xref py py-meth docutils literal"><span class="pre">MutableBase.coerce()</span></tt></a> method in conjunction with
 
450
objects of type <a class="reference internal" href="#sqlalchemy.ext.mutable.MutableComposite" title="sqlalchemy.ext.mutable.MutableComposite"><tt class="xref py py-class docutils literal"><span class="pre">MutableComposite</span></tt></a>.</p>
 
451
</div>
427
452
<div class="section" id="id1">
428
453
<h3>Supporting Pickling<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
429
454
<p>As is the case with <a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable" title="sqlalchemy.ext.mutable.Mutable"><tt class="xref py py-class docutils literal"><span class="pre">Mutable</span></tt></a>, the <a class="reference internal" href="#sqlalchemy.ext.mutable.MutableComposite" title="sqlalchemy.ext.mutable.MutableComposite"><tt class="xref py py-class docutils literal"><span class="pre">MutableComposite</span></tt></a> helper
452
477
<dl class="class">
453
478
<dt id="sqlalchemy.ext.mutable.MutableBase">
454
479
<em class="property">class </em><tt class="descclassname">sqlalchemy.ext.mutable.</tt><tt class="descname">MutableBase</tt><a class="headerlink" href="#sqlalchemy.ext.mutable.MutableBase" title="Permalink to this definition">¶</a></dt>
455
 
<dd><p>Common base class to <a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable" title="sqlalchemy.ext.mutable.Mutable"><tt class="xref py py-class docutils literal"><span class="pre">Mutable</span></tt></a> and <a class="reference internal" href="#sqlalchemy.ext.mutable.MutableComposite" title="sqlalchemy.ext.mutable.MutableComposite"><tt class="xref py py-class docutils literal"><span class="pre">MutableComposite</span></tt></a>.</p>
 
480
<dd><p>Common base class to <a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable" title="sqlalchemy.ext.mutable.Mutable"><tt class="xref py py-class docutils literal"><span class="pre">Mutable</span></tt></a>
 
481
and <a class="reference internal" href="#sqlalchemy.ext.mutable.MutableComposite" title="sqlalchemy.ext.mutable.MutableComposite"><tt class="xref py py-class docutils literal"><span class="pre">MutableComposite</span></tt></a>.</p>
456
482
<dl class="attribute">
457
483
<dt id="sqlalchemy.ext.mutable.MutableBase._parents">
458
484
<tt class="descname">_parents</tt><a class="headerlink" href="#sqlalchemy.ext.mutable.MutableBase._parents" title="Permalink to this definition">¶</a></dt>
462
488
it is accessed, returning the same object upon subsequent access.</p>
463
489
</dd></dl>
464
490
 
 
491
<dl class="classmethod">
 
492
<dt id="sqlalchemy.ext.mutable.MutableBase.coerce">
 
493
<em class="property">classmethod </em><tt class="descname">coerce</tt><big>(</big><em>key</em>, <em>value</em><big>)</big><a class="headerlink" href="#sqlalchemy.ext.mutable.MutableBase.coerce" title="Permalink to this definition">¶</a></dt>
 
494
<dd><p>Given a value, coerce it into the target type.</p>
 
495
<p>Can be overridden by custom subclasses to coerce incoming
 
496
data into a particular type.</p>
 
497
<p>By default, raises <tt class="docutils literal"><span class="pre">ValueError</span></tt>.</p>
 
498
<p>This method is called in different scenarios depending on if
 
499
the parent class is of type <a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable" title="sqlalchemy.ext.mutable.Mutable"><tt class="xref py py-class docutils literal"><span class="pre">Mutable</span></tt></a> or of type
 
500
<a class="reference internal" href="#sqlalchemy.ext.mutable.MutableComposite" title="sqlalchemy.ext.mutable.MutableComposite"><tt class="xref py py-class docutils literal"><span class="pre">MutableComposite</span></tt></a>.  In the case of the former, it is called
 
501
for both attribute-set operations as well as during ORM loading
 
502
operations.  For the latter, it is only called during attribute-set
 
503
operations; the mechanics of the <a class="reference internal" href="../mapper_config.html#sqlalchemy.orm.composite" title="sqlalchemy.orm.composite"><tt class="xref py py-func docutils literal"><span class="pre">composite()</span></tt></a> construct
 
504
handle coercion during load operations.</p>
 
505
<table class="docutils field-list" frame="void" rules="none">
 
506
<col class="field-name" />
 
507
<col class="field-body" />
 
508
<tbody valign="top">
 
509
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
 
510
<li><strong>key</strong> &#8211; string name of the ORM-mapped attribute being set.</li>
 
511
<li><strong>value</strong> &#8211; the incoming value.</li>
 
512
</ul>
 
513
</td>
 
514
</tr>
 
515
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the method should return the coerced value, or raise
 
516
<tt class="docutils literal"><span class="pre">ValueError</span></tt> if the coercion cannot be completed.</p>
 
517
</td>
 
518
</tr>
 
519
</tbody>
 
520
</table>
 
521
</dd></dl>
 
522
 
465
523
</dd></dl>
466
524
 
467
525
<dl class="class">
485
543
<span class="p">)</span></pre></div>
486
544
</div>
487
545
<p>Note that the returned type is always an instance, even if a class
488
 
is given, and that only columns which are declared specifically with that
489
 
type instance receive additional instrumentation.</p>
 
546
is given, and that only columns which are declared specifically with
 
547
that type instance receive additional instrumentation.</p>
490
548
<p>To associate a particular mutable type with all occurrences of a
491
549
particular type, use the <a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable.associate_with" title="sqlalchemy.ext.mutable.Mutable.associate_with"><tt class="xref py py-meth docutils literal"><span class="pre">Mutable.associate_with()</span></tt></a> classmethod
492
550
of the particular <tt class="xref py py-meth docutils literal"><span class="pre">Mutable()</span></tt> subclass to establish a global
506
564
<em class="property">classmethod </em><tt class="descname">associate_with</tt><big>(</big><em>sqltype</em><big>)</big><a class="headerlink" href="#sqlalchemy.ext.mutable.Mutable.associate_with" title="Permalink to this definition">¶</a></dt>
507
565
<dd><p>Associate this wrapper with all future mapped columns
508
566
of the given type.</p>
509
 
<p>This is a convenience method that calls <tt class="docutils literal"><span class="pre">associate_with_attribute</span></tt> automatically.</p>
 
567
<p>This is a convenience method that calls
 
568
<tt class="docutils literal"><span class="pre">associate_with_attribute</span></tt> automatically.</p>
510
569
<div class="admonition warning">
511
570
<p class="first admonition-title">Warning</p>
512
571
<p class="last">The listeners established by this method are <em>global</em>
513
572
to all mappers, and are <em>not</em> garbage collected.   Only use
514
 
<a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable.associate_with" title="sqlalchemy.ext.mutable.Mutable.associate_with"><tt class="xref py py-meth docutils literal"><span class="pre">associate_with()</span></tt></a> for types that are permanent to an application,
515
 
not with ad-hoc types else this will cause unbounded growth
516
 
in memory usage.</p>
 
573
<a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable.associate_with" title="sqlalchemy.ext.mutable.Mutable.associate_with"><tt class="xref py py-meth docutils literal"><span class="pre">associate_with()</span></tt></a> for types that are permanent to an
 
574
application, not with ad-hoc types else this will cause unbounded
 
575
growth in memory usage.</p>
517
576
</div>
518
577
</dd></dl>
519
578
 
540
599
events on a SQLAlchemy &#8220;composite&#8221; object to its
541
600
owning parent or parents.</p>
542
601
<p>See the example in <a class="reference internal" href="#mutable-composites"><em>Establishing Mutability on Composites</em></a> for usage information.</p>
543
 
<div class="admonition warning">
544
 
<p class="first admonition-title">Warning</p>
545
 
<p class="last">The listeners established by the <a class="reference internal" href="#sqlalchemy.ext.mutable.MutableComposite" title="sqlalchemy.ext.mutable.MutableComposite"><tt class="xref py py-class docutils literal"><span class="pre">MutableComposite</span></tt></a>
546
 
class are <em>global</em> to all mappers, and are <em>not</em> garbage collected.   Only use
547
 
<a class="reference internal" href="#sqlalchemy.ext.mutable.MutableComposite" title="sqlalchemy.ext.mutable.MutableComposite"><tt class="xref py py-class docutils literal"><span class="pre">MutableComposite</span></tt></a> for types that are permanent to an application,
548
 
not with ad-hoc types else this will cause unbounded growth
549
 
in memory usage.</p>
550
 
</div>
551
602
<dl class="method">
552
603
<dt id="sqlalchemy.ext.mutable.MutableComposite.changed">
553
604
<tt class="descname">changed</tt><big>(</big><big>)</big><a class="headerlink" href="#sqlalchemy.ext.mutable.MutableComposite.changed" title="Permalink to this definition">¶</a></dt>
556
607
 
557
608
</dd></dl>
558
609
 
 
610
<dl class="class">
 
611
<dt id="sqlalchemy.ext.mutable.MutableDict">
 
612
<em class="property">class </em><tt class="descclassname">sqlalchemy.ext.mutable.</tt><tt class="descname">MutableDict</tt><a class="headerlink" href="#sqlalchemy.ext.mutable.MutableDict" title="Permalink to this definition">¶</a></dt>
 
613
<dd><p>Bases: <a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable" title="sqlalchemy.ext.mutable.Mutable"><tt class="xref py py-class docutils literal"><span class="pre">sqlalchemy.ext.mutable.Mutable</span></tt></a>, <tt class="xref py py-class docutils literal"><span class="pre">dict</span></tt></p>
 
614
<p>A dictionary type that implements <a class="reference internal" href="#sqlalchemy.ext.mutable.Mutable" title="sqlalchemy.ext.mutable.Mutable"><tt class="xref py py-class docutils literal"><span class="pre">Mutable</span></tt></a>.</p>
 
615
<p class="versionadded">
 
616
<span class="versionmodified">New in version 0.8.</span></p>
 
617
<dl class="classmethod">
 
618
<dt id="sqlalchemy.ext.mutable.MutableDict.coerce">
 
619
<em class="property">classmethod </em><tt class="descname">coerce</tt><big>(</big><em>key</em>, <em>value</em><big>)</big><a class="headerlink" href="#sqlalchemy.ext.mutable.MutableDict.coerce" title="Permalink to this definition">¶</a></dt>
 
620
<dd><p>Convert plain dictionary to MutableDict.</p>
 
621
</dd></dl>
 
622
 
 
623
</dd></dl>
 
624
 
559
625
</div>
560
626
</div>
561
627
 
570
636
        <a href="orderinglist.html" title="next chapter">Ordering List</a>
571
637
 
572
638
    <div id="docs-copyright">
573
 
        &copy; <a href="../../copyright.html">Copyright</a> 2007-2012, the SQLAlchemy authors and contributors.
 
639
        &copy; <a href="../../copyright.html">Copyright</a> 2007-2013, the SQLAlchemy authors and contributors.
574
640
        Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
575
641
    </div>
576
642
</div>