<?xml version="1.0" encoding="UTF-8"?>
<feed
  xmlns="http://www.w3.org/2005/Atom"
  xmlns:thr="http://purl.org/syndication/thread/1.0"
  xml:lang="en"
   >
  <title type="text">zzzeek</title>
  <subtitle type="text">mostly computer stuff</subtitle>

  <updated>2012-02-07T16:16:27Z</updated>
  <generator uri="http://blogofile.com/">Blogofile</generator>

  <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org" />
  <id>http://techspot.zzzeek.org/feed/atom/</id>
  <link rel="self" type="application/atom+xml" href="http://techspot.zzzeek.org/feed/atom/" />
  <entry>
    <author>
      <name></name>
      <uri>http://techspot.zzzeek.org</uri>
    </author>
    <title type="html"><![CDATA[Patterns Implemented by SQLAlchemy]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2012/02/07/patterns-implemented-by-sqlalchemy" />
    <id>http://techspot.zzzeek.org/2012/02/07/patterns-implemented-by-sqlalchemy</id>
    <updated>2012-02-07T17:01:00Z</updated>
    <published>2012-02-07T17:01:00Z</published>
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <summary type="html"><![CDATA[Patterns Implemented by SQLAlchemy]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2012/02/07/patterns-implemented-by-sqlalchemy"><![CDATA[<div class="document">
<p>When I first created SQLAlchemy, I knew I wanted to create something
significant. It was by no means the first ORM or database abstraction layer
I'd written; by 2005, I'd probably written about a dozen abstraction layers in
several languages, including in Java, Perl, C and C++ (really bad C and even
worse C++, one that talked to ODBC and another that communicated with
Microsoft's ancient <a class="reference external" href="http://msdn.microsoft.com/en-us/library/aa936939">DB-LIB</a> directly). All of these
abstraction layers were in the range of awful to mediocre, and certainly none
were anywhere near release-quality; even by late-90's to early-2000's standards.
They were all created for closed-source applications written on the job, but
each one did its job very well.</p>
<p>It was the repetitive creation of the same patterns over and over again that
made apparent the kinds of things a real toolkit should have, as well as
increased the urge to actually go through with it, so that I wouldn't have to
invent new database interaction layers for every new project, or worse, be
compelled by management to use whatever mediocre product they had read about
the week before (keeping in mind I was made to use such disasters as
<a class="reference external" href="http://en.wikipedia.org/wiki/Enterprise_JavaBeans#EJB_1.0_.281998-03-24.29">EJB 1.0</a>).
But at the same time it was apparent to me that I was going
to need to do some research up front as well. The primary book I used for this
research was <a class="reference external" href="http://www.martinfowler.com/books.html#eaa">Patterns of Enterprise Archictecture</a> by Martin Fowler. When reading
this book, about half the patterns were ones that I'd already used implicitly,
and the other half were ones that I was previously not entirely aware of.</p>
<p>Sometimes I read comments from new users expressing confusion or frustration
with SQLAlchemy's concepts. Maybe some of these users
are not only new to SQLAlchemy but are new to database abstraction layers in
general, and some maybe even to relational databases themselves. What I'd like to
lay out here is just how many of POEAA's patterns SQLAlchemy is built upon. If
you're new to SQLAlchemy, my hope is that this list might help to de-mystify
where these patterns come from.</p>
<p>These links are from <a class="reference external" href="http://martinfowler.com/eaaCatalog/">Catalog of Patterns of Enterprise Architecture</a>.</p>
<ul class="simple">
<li><a class="reference external" href="http://martinfowler.com/eaaCatalog/dataMapper.html">Data Mapper</a> - The
key to this pattern is that object-relational mapping is applied to a
user-defined class in a transparent way, keeping the details of persistence
separate from the public interface of the class. SQLAlchemy's classical
mapping system, which is the usage of the <a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/mapper_config.html#sqlalchemy.orm.mapper">mapper()</a>
function to link a class with table metadata, implemented this pattern as
fully as possible. In modern SQLAlchemy, we use the <a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/extensions/declarative.html">Declarative</a>
pattern which combines table metadata with the class' declaration as a
shortcut to using <a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/mapper_config.html#sqlalchemy.orm.mapper">mapper()</a>,
but the persistence API remains separate.</li>
<li><a class="reference external" href="http://martinfowler.com/eaaCatalog/unitOfWork.html">Unit of Work</a> - This
pattern is where the system transparently keeps track of changes to objects
and periodically flushes all those pending changes out to the database.
SQLAlchemy's <a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/session.html">Session</a> implements this
pattern fully in a manner similar to that of Hibernate.</li>
<li><a class="reference external" href="http://martinfowler.com/eaaCatalog/identityMap.html">Identity Map</a> - This
is an essential pattern that establishes unique identities for each object
within a particular session, based on database identity. No ORM should be
without this feature, as working with object structures and applications of
the most moderate complexity is vastly simplified and made more efficient with this
pattern in place.</li>
<li><a class="reference external" href="http://martinfowler.com/eaaCatalog/metadataMapping.html">Metadata Mapping</a> - this chapter
in the book is where the name <a class="reference external" href="http://docs.sqlalchemy.org/en/latest/core/schema.html">MetaData</a> comes from.   The exact
correspondence to Fowler's pattern would be the combination of <tt class="docutils literal">mapper()</tt>
and <tt class="docutils literal">Table</tt>.</li>
<li><a class="reference external" href="http://martinfowler.com/eaaCatalog/queryObject.html">Query Object</a> - Both
the ORM <a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/query.html">Query</a> and
the Core <a class="reference external" href="http://docs.sqlalchemy.org/en/latest/core/tutorial.html#selecting">select()</a>
construct are built on this pattern.</li>
<li><a class="reference external" href="http://martinfowler.com/eaaCatalog/repository.html">Repository</a> - An
interface that serves as the gateway to the database, in terms of
object-relational mappings. This is the SQLAlchemy <a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/session.html">Session</a>.</li>
<li><a class="reference external" href="http://martinfowler.com/eaaCatalog/lazyLoad.html">Lazy Load</a> - Load a
related collection or object as you need it. SQLAlchemy, like Hibernate, has
<a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/loading.html">a lot of options</a>
in how attributes can load things.</li>
<li><a class="reference external" href="http://martinfowler.com/eaaCatalog/identityField.html">Identity Field</a> -
Represent the primary key of a table's row within the object that represents
it.</li>
<li><a class="reference external" href="http://martinfowler.com/eaaCatalog/foreignKeyMapping.html">Foreign Key Mapping</a> - Database
foreign keys are represented using <a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/relationships.html">relationships</a> in the
object model.</li>
<li><a class="reference external" href="http://martinfowler.com/eaaCatalog/associationTableMapping.html">Association Table Mapping</a> - A
class can be mapped that represents information about how two objects are
related to each other. Use the <a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/relationships.html#association-object">Association Object</a>
for this pattern.</li>
<li><a class="reference external" href="http://martinfowler.com/eaaCatalog/embeddedValue.html">Embedded Value</a> -
a value inline on an object represents multiple columns. SQLAlchemy provides
the <a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/mapper_config.html#composite-column-types">Composite</a>
pattern here.</li>
<li><a class="reference external" href="http://martinfowler.com/eaaCatalog/serializedLOB.html">Serialized LOB</a> -
Sometimes you just want to stuff all the objects into a BLOB. Use the
<a class="reference external" href="http://docs.sqlalchemy.org/en/latest/core/types.html#sqlalchemy.types.PickleType">PickleType</a>
or roll a <a class="reference external" href="http://docs.sqlalchemy.org/en/latest/core/types.html#marshal-json-strings">JSON type</a>.</li>
<li><a class="reference external" href="http://martinfowler.com/eaaCatalog/inheritanceMappers.html">Inheritance Mappers</a> - Represent
class hierarchies within database tables. See <a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/inheritance.html">Inheritance Mapping</a>.<ul>
<li>Single Table Inheritance - <a class="reference external" href="http://martinfowler.com/eaaCatalog/singleTableInheritance.html">POEAA (1)</a> -
<a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/inheritance.html#single-table-inheritance">SQLA (1)</a></li>
<li>Class Table Inheritance - <a class="reference external" href="http://martinfowler.com/eaaCatalog/classTableInheritance.html">POEAA (2)</a> -
<a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/inheritance.html#joined-table-inheritance">SQLA (2)</a></li>
<li>Concrete Table Inheritance - <a class="reference external" href="http://martinfowler.com/eaaCatalog/concreteTableInheritance.html">POEAA (3)</a> -
<a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/inheritance.html#concrete-table-inheritance">SQLA (3)</a></li>
</ul>
</li>
<li><a class="reference external" href="http://martinfowler.com/eaaCatalog/optimisticOfflineLock.html">Optimistic Offline Lock</a> - Set up a
<a class="reference external" href="http://docs.sqlalchemy.org/en/latest/orm/mapper_config.html#sqlalchemy.orm.mapper">version id</a>
on your mapping to enable this feature in SQLAlchemy.</li>
</ul>
<p>Thanks for reading!</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://techspot.zzzeek.org</uri>
    </author>
    <title type="html"><![CDATA[Django-style Database Routers in SQLAlchemy]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy" />
    <id>http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy</id>
    <updated>2012-01-11T23:50:00Z</updated>
    <published>2012-01-11T23:50:00Z</published>
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <summary type="html"><![CDATA[Django-style Database Routers in SQLAlchemy]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy"><![CDATA[<div class="document">
<p>As luck would have it, I'm currently assigned to work with some existing Django code.
It's been quite a long time I've gone without needing to do so, but now that I'm there, I
can start fleshing out how some of the use cases for Django can be approximated in SQLAlchemy.</p>
<p>Today it's something that's really quite simple - how to mimic the <a class="reference external" href="https://docs.djangoproject.com/en/1.3/topics/db/multi-db/#an-example">Multiple Databases</a>
example in Django's docs.   The Django approach is to build a &quot;router&quot; object into the system
which can then decide on a query-by-query basis which of several databases should be used for each query.
For this, they provide an interface which includes <tt class="docutils literal">db_for_read()</tt>, <tt class="docutils literal">db_for_write()</tt>, <tt class="docutils literal">allow_relation()</tt>
and <tt class="docutils literal">allow_syncdb()</tt>.  In particular, <tt class="docutils literal">db_for_read()</tt> and <tt class="docutils literal">db_for_write()</tt> are used
when emitting most SQL.    These receive an argument called <tt class="docutils literal">model</tt>, which the docs state is a &quot;type&quot;,
i.e. a class.   Because the database determination is based on type, we call this in
SQLAlchemy <em>vertical partitioning</em> - databases are partitioned along types.</p>
<p>The specific example here has the following behavior:</p>
<ol class="arabic simple">
<li>Write operations occur on a database referred to as <tt class="docutils literal">master</tt>.</li>
<li>Read operations are split among two different databases
referred to as <tt class="docutils literal">slave1</tt> and <tt class="docutils literal">slave2</tt>.</li>
<li>Operations for a specific subset of classes denoted by <tt class="docutils literal">myapp</tt>
occur on a database referred to as <tt class="docutils literal">other</tt>.</li>
</ol>
<p>When using SQLAlchemy, we of course don't have the concept of &quot;apps&quot; as a
delineating factor between different types.   So we'll use the old fashioned approach
and just use the type itself, that is, what hierarchy it inherits from,
to determine which subsystem of the application it heralds from.</p>
<p>The SQLAlchemy <tt class="docutils literal">Session</tt> makes all decisions about what <tt class="docutils literal">Engine</tt> to use within the
<a class="reference external" href="http://www.sqlalchemy.org/docs/orm/session.html#sqlalchemy.orm.session.Session.get_bind">get_bind()</a>
method.   This method is given pretty much the same information that <tt class="docutils literal">db_for_read()</tt> and <tt class="docutils literal">db_for_write()</tt>
receive, where a <tt class="docutils literal">Mapper</tt> is passed in, if available, and we can also check if the operation is a
&quot;write&quot; just by checking if the <tt class="docutils literal">Session</tt> is flushing.</p>
<div class="section" id="imports">
<h1>Imports</h1>
<p>We'll build up our example in the usual way, as a full script broken out.  First the imports:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">Column</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">String</span><span class="p">,</span> <span class="n">MetaData</span><span class="p">,</span> <span class="n">create_engine</span>
<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="n">scoped_session</span><span class="p">,</span> <span class="n">sessionmaker</span><span class="p">,</span> <span class="n">Session</span>
<span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span> <span class="n">declarative_base</span>
<span class="kn">import</span> <span class="nn">random</span>
<span class="kn">import</span> <span class="nn">shutil</span>
</pre></div>



</div>
<div class="section" id="engine-registry">
<h1>Engine Registry</h1>
<p>Then, some <tt class="docutils literal">Engine</tt> instances.  Note that, unlike Django, SQLAlchemy is not a
framework, and doesn't have a <tt class="docutils literal">settings.py</tt>
file or an existing registry of engines.   Assuming we can decide on a decent
place to put our own registry, we just stick them in a <tt class="docutils literal">dict</tt>:</p>


<div class="pygments_manni"><pre><span class="n">engines</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">&#39;master&#39;</span><span class="p">:</span> <span class="n">create_engine</span><span class="p">(</span><span class="s">&#39;sqlite:///master.db&#39;</span><span class="p">,</span>
                            <span class="n">logging_name</span><span class="o">=</span><span class="s">&#39;master&#39;</span><span class="p">),</span>
    <span class="s">&#39;other&#39;</span><span class="p">:</span> <span class="n">create_engine</span><span class="p">(</span><span class="s">&#39;sqlite:///other.db&#39;</span><span class="p">,</span>
                            <span class="n">logging_name</span><span class="o">=</span><span class="s">&#39;other&#39;</span><span class="p">),</span>
    <span class="s">&#39;slave1&#39;</span><span class="p">:</span> <span class="n">create_engine</span><span class="p">(</span><span class="s">&#39;sqlite:///slave1.db&#39;</span><span class="p">,</span>
                            <span class="n">logging_name</span><span class="o">=</span><span class="s">&#39;slave1&#39;</span><span class="p">),</span>
    <span class="s">&#39;slave2&#39;</span><span class="p">:</span> <span class="n">create_engine</span><span class="p">(</span><span class="s">&#39;sqlite:///slave2.db&#39;</span><span class="p">,</span>
                            <span class="n">logging_name</span><span class="o">=</span><span class="s">&#39;slave2&#39;</span><span class="p">),</span>
    <span class="p">}</span>
</pre></div>



<p>The example here uses SQLite databases, so that it's quick and easy to actually run
the script.   However, as I'm not familiar with replication functionality in SQLite,
we'll have to &quot;fake&quot; the part where &quot;master&quot; replicates to &quot;slave&quot;, just for the
sake of example.</p>
</div>
<div class="section" id="routing">
<h1>Routing</h1>
<p>Next comes our implementation of <tt class="docutils literal">get_bind()</tt>.  We're building into a more open-ended space
here, which can good or bad thing, depending on where you're coming from.
Instead of building two &quot;router&quot; classes with two db routing methods each,
we just need to make one method with some conditionals:</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">RoutingSession</span><span class="p">(</span><span class="n">Session</span><span class="p">):</span>

    <span class="k">def</span> <span class="nf">get_bind</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mapper</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">clause</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">mapper</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">mapper</span><span class="o">.</span><span class="n">class_</span><span class="p">,</span> <span class="n">OtherBase</span><span class="p">):</span>
            <span class="k">return</span> <span class="n">engines</span><span class="p">[</span><span class="s">&#39;other&#39;</span><span class="p">]</span>
        <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">_flushing</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">engines</span><span class="p">[</span><span class="s">&#39;master&#39;</span><span class="p">]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">engines</span><span class="p">[</span>
                    <span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">([</span><span class="s">&#39;slave1&#39;</span><span class="p">,</span><span class="s">&#39;slave2&#39;</span><span class="p">])</span>
                <span class="p">]</span>
</pre></div>



<p>So above, we use a three-state conditional to make exactly those same choices
the Django example does.   When we want to detect the classes destined for the
&quot;other&quot; engine, we look for a particular base class called <tt class="docutils literal">OtherBase</tt>.  We
could just as easily do other kinds of checks here, such as checking for a particular
attribute on the class.</p>
<p>We also look at a state variable called <tt class="docutils literal">_flushing</tt> to determine operations destined
for the <tt class="docutils literal">master</tt>.   The <tt class="docutils literal">Session._flushing</tt> flag is set as soon as the flush
procedure begins, and remains on until the method completes.  SQLAlchemy uses this
flag mainly to prevent <a class="reference external" href="http://en.wikipedia.org/wiki/Reentrancy_%28computing%29">re-entrant</a>
calls to autoflush when it's already inside of the flush process.</p>
<p>That's all we need in the way of <tt class="docutils literal">Session</tt>, for the moment. To wire this <tt class="docutils literal">Session</tt>
up into the standard <tt class="docutils literal"><span class="pre">scoped_session(sessionmaker())</span></tt> process, we can pass it
into <tt class="docutils literal">sessionmaker()</tt>:</p>


<div class="pygments_manni"><pre><span class="n">Session</span> <span class="o">=</span> <span class="n">scoped_session</span><span class="p">(</span><span class="n">sessionmaker</span><span class="p">(</span><span class="n">class_</span><span class="o">=</span><span class="n">RoutingSession</span><span class="p">))</span>
</pre></div>



</div>
<div class="section" id="model-setup">
<h1>Model Setup</h1>
<p>Next, let's build up the &quot;model&quot;.   This is the part where we need to come up with
an answer for Django's <tt class="docutils literal">syncdb</tt> feature, which of course in SQLAlchemy is <tt class="docutils literal">MetaData.create_all()</tt>.
We now have two different schemas - one schema is shared
between <tt class="docutils literal">master</tt>, <tt class="docutils literal">slave1</tt>, and <tt class="docutils literal">slave2</tt>, the other is destined for <tt class="docutils literal">other</tt>.  We'll
split out our table metadata among these backends using two different <tt class="docutils literal">MetaData()</tt> objects.
To achieve that transparently, I'll use a trick I don't think people are quite aware of yet,
which is to use abstract declarative bases.</p>
<p>Starting with a useful declarative base that will give us an <tt class="docutils literal">id</tt> and a <tt class="docutils literal">data</tt> column,
as well as a decent <tt class="docutils literal">__repr__()</tt>:</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">Base</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">data</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="mi">50</span><span class="p">))</span>
    <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s">(id=</span><span class="si">%r</span><span class="s">, data=</span><span class="si">%r</span><span class="s">)&quot;</span> <span class="o">%</span> <span class="p">(</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">,</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span>
        <span class="p">)</span>

<span class="n">Base</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">(</span><span class="n">cls</span><span class="o">=</span><span class="n">Base</span><span class="p">)</span>
</pre></div>



<p>We then split out <tt class="docutils literal">Base</tt> into two subtypes, which won't be mapped.  To tell declarative
not to map these non-mixin, direct descendants of <tt class="docutils literal">Base</tt>, we use a fairly new
flag called <tt class="docutils literal">__abstract__</tt>:</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">DefaultBase</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
    <span class="n">__abstract__</span> <span class="o">=</span> <span class="bp">True</span>
    <span class="n">metadata</span> <span class="o">=</span> <span class="n">MetaData</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">OtherBase</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
    <span class="n">__abstract__</span> <span class="o">=</span> <span class="bp">True</span>
    <span class="n">metadata</span> <span class="o">=</span> <span class="n">MetaData</span><span class="p">()</span>
</pre></div>



<p>and holy crap look at that a <tt class="docutils literal">MetaData</tt> on each one!  You can do that?   Sure can - the
classes we build on top of <tt class="docutils literal">DefaultBase</tt> will put the <tt class="docutils literal">Table</tt> objects into one <tt class="docutils literal">MetaData</tt>,
the classes we built on top of <tt class="docutils literal">OtherBase</tt> will put them into another.  We've basically
just replaced the <tt class="docutils literal">.metadata</tt> attribute declarative sets up with our own - there's no magic.
The <tt class="docutils literal">DefaultBase</tt> and <tt class="docutils literal">OtherBase</tt> classes are also not mapped and are transparent to the mapping mechanism.</p>
<p>Let's build out three &quot;models&quot; (I really prefer to say &quot;class&quot;, let's see if I can get to the end
of this post without complaining more about it...):</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">Model1</span><span class="p">(</span><span class="n">DefaultBase</span><span class="p">):</span>
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;model1&#39;</span>

<span class="k">class</span> <span class="nc">Model2</span><span class="p">(</span><span class="n">DefaultBase</span><span class="p">):</span>
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;model2&#39;</span>

<span class="k">class</span> <span class="nc">Model3</span><span class="p">(</span><span class="n">OtherBase</span><span class="p">):</span>
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;model3&#39;</span>
</pre></div>



<p>Bang.  For those unfamiliar with declarative, because these objects ultimately descend from <tt class="docutils literal">Base</tt>
above, they will have an <tt class="docutils literal">id</tt> and a <tt class="docutils literal">data</tt> column available, where <tt class="docutils literal">id</tt> is a surrogate primary key.</p>
</div>
<div class="section" id="table-creation">
<h1>Table Creation</h1>
<p>We use <tt class="docutils literal">MetaData.create_all()</tt> here.  Anything that's <tt class="docutils literal">DefaultBase</tt> should
have tables created in <tt class="docutils literal">master</tt>, <tt class="docutils literal">slave1</tt>, <tt class="docutils literal">slave2</tt>:</p>


<div class="pygments_manni"><pre><span class="k">for</span> <span class="n">eng</span> <span class="ow">in</span> <span class="s">&#39;master&#39;</span><span class="p">,</span> <span class="s">&#39;slave1&#39;</span><span class="p">,</span> <span class="s">&#39;slave2&#39;</span><span class="p">:</span>
    <span class="n">DefaultBase</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">create_all</span><span class="p">(</span><span class="n">engines</span><span class="p">[</span><span class="n">eng</span><span class="p">])</span>
</pre></div>



<p><tt class="docutils literal">OtherBase</tt> then goes to <tt class="docutils literal">other</tt>:</p>


<div class="pygments_manni"><pre><span class="n">OtherBase</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">create_all</span><span class="p">(</span><span class="n">engines</span><span class="p">[</span><span class="s">&#39;other&#39;</span><span class="p">])</span>
</pre></div>



</div>
<div class="section" id="usage">
<h1>Usage</h1>
<p>We now have the tables built, we can show off things getting sent to <tt class="docutils literal">master</tt> with
a basic <tt class="docutils literal">commit()</tt>:</p>


<div class="pygments_manni"><pre><span class="n">s</span> <span class="o">=</span> <span class="n">Session</span><span class="p">()</span>

<span class="n">s</span><span class="o">.</span><span class="n">add_all</span><span class="p">([</span>
    <span class="n">Model1</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="s">&#39;m1_a&#39;</span><span class="p">),</span>
    <span class="n">Model2</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="s">&#39;m2_a&#39;</span><span class="p">),</span>
    <span class="n">Model1</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="s">&#39;m1_b&#39;</span><span class="p">),</span>
    <span class="n">Model2</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="s">&#39;m2_b&#39;</span><span class="p">),</span>
    <span class="n">Model3</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="s">&#39;m3_a&#39;</span><span class="p">),</span>
    <span class="n">Model3</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="s">&#39;m3_b&#39;</span><span class="p">),</span>
<span class="p">])</span>
<span class="n">s</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
</pre></div>



<p>If we have SQL echoing on, we'd see transactions starting on each of <tt class="docutils literal">master</tt>
and <tt class="docutils literal">other</tt>, the requisite <tt class="docutils literal">INSERT</tt> statements, then the two <tt class="docutils literal">COMMIT</tt>
calls.  Note that the <tt class="docutils literal">BEGIN</tt> for <tt class="docutils literal">other</tt> doesn't occur until the unit
of work actually comes across SQL destined for this engine:</p>


<div class="pygments_manni"><pre><span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">master</span> <span class="k">BEGIN</span> <span class="p">(</span><span class="k">implicit</span><span class="p">)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">master</span> <span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">model1</span> <span class="p">(</span><span class="k">data</span><span class="p">)</span> <span class="k">VALUES</span> <span class="p">(</span><span class="o">?</span><span class="p">)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">master</span> <span class="p">(</span><span class="s1">&#39;m1_a&#39;</span><span class="p">,)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">master</span> <span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">model1</span> <span class="p">(</span><span class="k">data</span><span class="p">)</span> <span class="k">VALUES</span> <span class="p">(</span><span class="o">?</span><span class="p">)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">master</span> <span class="p">(</span><span class="s1">&#39;m1_b&#39;</span><span class="p">,)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">other</span> <span class="k">BEGIN</span> <span class="p">(</span><span class="k">implicit</span><span class="p">)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">other</span> <span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">model3</span> <span class="p">(</span><span class="k">data</span><span class="p">)</span> <span class="k">VALUES</span> <span class="p">(</span><span class="o">?</span><span class="p">)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">other</span> <span class="p">(</span><span class="s1">&#39;m3_a&#39;</span><span class="p">,)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">other</span> <span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">model3</span> <span class="p">(</span><span class="k">data</span><span class="p">)</span> <span class="k">VALUES</span> <span class="p">(</span><span class="o">?</span><span class="p">)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">other</span> <span class="p">(</span><span class="s1">&#39;m3_b&#39;</span><span class="p">,)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">master</span> <span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">model2</span> <span class="p">(</span><span class="k">data</span><span class="p">)</span> <span class="k">VALUES</span> <span class="p">(</span><span class="o">?</span><span class="p">)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">master</span> <span class="p">(</span><span class="s1">&#39;m2_a&#39;</span><span class="p">,)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">master</span> <span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">model2</span> <span class="p">(</span><span class="k">data</span><span class="p">)</span> <span class="k">VALUES</span> <span class="p">(</span><span class="o">?</span><span class="p">)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">master</span> <span class="p">(</span><span class="s1">&#39;m2_b&#39;</span><span class="p">,)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">other</span> <span class="k">COMMIT</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="p">.</span><span class="n">engine</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">Engine</span><span class="p">.</span><span class="n">master</span> <span class="k">COMMIT</span>
</pre></div>



<p>Now let's query.   Normally, if we had a Postgresql or MySQL replication environment set up,
the data we write to <tt class="docutils literal">master</tt> would have been copied out to <tt class="docutils literal">slave1</tt> and <tt class="docutils literal">slave2</tt>.
So cover your eyes for a moment while we pretend:</p>


<div class="pygments_manni"><pre><span class="c">##### PRETEND PRETEND PRETEND ######</span>
<span class="c"># now let&#39;s pretend &quot;master&#39; is replicating to &quot;slave1&quot;, &quot;slave2&quot;</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="s">&quot;master.db&quot;</span><span class="p">,</span> <span class="s">&quot;slave1.db&quot;</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="s">&quot;master.db&quot;</span><span class="p">,</span> <span class="s">&quot;slave2.db&quot;</span><span class="p">)</span>
<span class="c">##### END PRETEND END PRETEND END PRETEND ######</span>
</pre></div>



<p>(note that SQLAlchemy as of 0.7 doesn't use a connection pool by default
when it talks to SQLite - it just opens from the
file each time.  As long as nobody's talking to the database, we can swap out the file).</p>
<p>We can do some querying - SQL echoing is displayed inline here:</p>


<div class="pygments_manni"><pre><span class="o">&gt;&gt;&gt;</span> <span class="k">print</span> <span class="n">s</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Model1</span><span class="p">)</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">base</span><span class="o">.</span><span class="n">Engine</span><span class="o">.</span><span class="n">slave2</span> <span class="n">BEGIN</span> <span class="p">(</span><span class="n">implicit</span><span class="p">)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">base</span><span class="o">.</span><span class="n">Engine</span><span class="o">.</span><span class="n">slave2</span> <span class="n">SELECT</span> <span class="n">model1</span><span class="o">.</span><span class="n">id</span> <span class="n">AS</span> <span class="n">model1_id</span><span class="p">,</span> <span class="n">model1</span><span class="o">.</span><span class="n">data</span> <span class="n">AS</span> <span class="n">model1_data</span>
<span class="n">FROM</span> <span class="n">model1</span>
<span class="p">[</span><span class="n">Model1</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s">&#39;m1_a&#39;</span><span class="p">),</span> <span class="n">Model1</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s">&#39;m1_b&#39;</span><span class="p">)]</span>

<span class="o">&gt;&gt;&gt;</span> <span class="k">print</span> <span class="n">s</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Model2</span><span class="p">)</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">base</span><span class="o">.</span><span class="n">Engine</span><span class="o">.</span><span class="n">slave1</span> <span class="n">BEGIN</span> <span class="p">(</span><span class="n">implicit</span><span class="p">)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">base</span><span class="o">.</span><span class="n">Engine</span><span class="o">.</span><span class="n">slave1</span> <span class="n">SELECT</span> <span class="n">model2</span><span class="o">.</span><span class="n">id</span> <span class="n">AS</span> <span class="n">model2_id</span><span class="p">,</span> <span class="n">model2</span><span class="o">.</span><span class="n">data</span> <span class="n">AS</span> <span class="n">model2_data</span>
<span class="n">FROM</span> <span class="n">model2</span>
<span class="p">[</span><span class="n">Model2</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s">&#39;m2_a&#39;</span><span class="p">),</span> <span class="n">Model2</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s">&#39;m2_b&#39;</span><span class="p">)]</span>

<span class="o">&gt;&gt;&gt;</span> <span class="k">print</span> <span class="n">s</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Model3</span><span class="p">)</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">base</span><span class="o">.</span><span class="n">Engine</span><span class="o">.</span><span class="n">other</span> <span class="n">BEGIN</span> <span class="p">(</span><span class="n">implicit</span><span class="p">)</span>
<span class="n">INFO</span> <span class="n">sqlalchemy</span><span class="o">.</span><span class="n">engine</span><span class="o">.</span><span class="n">base</span><span class="o">.</span><span class="n">Engine</span><span class="o">.</span><span class="n">other</span> <span class="n">SELECT</span> <span class="n">model3</span><span class="o">.</span><span class="n">id</span> <span class="n">AS</span> <span class="n">model3_id</span><span class="p">,</span> <span class="n">model3</span><span class="o">.</span><span class="n">data</span> <span class="n">AS</span> <span class="n">model3_data</span>
<span class="n">FROM</span> <span class="n">model3</span>
<span class="p">[</span><span class="n">Model3</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s">&#39;m3_a&#39;</span><span class="p">),</span> <span class="n">Model3</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s">&#39;m3_b&#39;</span><span class="p">)]</span>
</pre></div>



</div>
<div class="section" id="manual-access">
<h1>Manual Access</h1>
<p>Django also includes a &quot;manual&quot; selection mode via the <tt class="docutils literal">using()</tt> modifier on the <tt class="docutils literal">QuerySet</tt> object.
Let's illustrate a modified version of our <tt class="docutils literal">RoutingSession</tt> with a similar method added.   We
add one more check in <tt class="docutils literal">get_bind()</tt>, to look for a local attribute called <tt class="docutils literal">name</tt> - then we
build a quick &quot;generative&quot; method that copies the state from one <tt class="docutils literal">RoutingSession</tt> into another,
so that the second session shares the same state:</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">RoutingSession</span><span class="p">(</span><span class="n">Session</span><span class="p">):</span>

    <span class="k">def</span> <span class="nf">get_bind</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mapper</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">clause</span><span class="o">=</span><span class="bp">None</span> <span class="p">):</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">engines</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">]</span>
        <span class="k">elif</span> <span class="n">mapper</span> <span class="ow">and</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">mapper</span><span class="o">.</span><span class="n">class_</span><span class="p">,</span> <span class="n">OtherBase</span><span class="p">):</span>
            <span class="k">return</span> <span class="n">engines</span><span class="p">[</span><span class="s">&#39;other&#39;</span><span class="p">]</span>
        <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">_flushing</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">engines</span><span class="p">[</span><span class="s">&#39;master&#39;</span><span class="p">]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">engines</span><span class="p">[</span>
                    <span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">([</span><span class="s">&#39;slave1&#39;</span><span class="p">,</span><span class="s">&#39;slave2&#39;</span><span class="p">])</span>
                <span class="p">]</span>

    <span class="n">_name</span> <span class="o">=</span> <span class="bp">None</span>
    <span class="k">def</span> <span class="nf">using_bind</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
        <span class="n">s</span> <span class="o">=</span> <span class="n">RoutingSession</span><span class="p">()</span>
        <span class="nb">vars</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="nb">vars</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
        <span class="n">s</span><span class="o">.</span><span class="n">_name</span> <span class="o">=</span> <span class="n">name</span>
        <span class="k">return</span> <span class="n">s</span>
</pre></div>



<p>So assuming we plugged in the above <tt class="docutils literal">Session</tt>, we can explicitly query the <tt class="docutils literal">master</tt>
as:</p>


<div class="pygments_manni"><pre><span class="n">m1</span> <span class="o">=</span> <span class="n">Session</span><span class="p">()</span><span class="o">.</span><span class="n">using_bind</span><span class="p">(</span><span class="s">&quot;master&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Model1</span><span class="p">)</span><span class="o">.</span><span class="n">first</span><span class="p">()</span>
</pre></div>



<p>Admittedly, the <tt class="docutils literal">using_bind()</tt> method above might be something I should add some helpers
for, like a <tt class="docutils literal">&#64;generative</tt> decorator similar to that available for <tt class="docutils literal">Query</tt>, so that
the <tt class="docutils literal">vars.update()</tt> approach is not needed.</p>
<p>I hope this example is useful, and sheds some light on how we do things in SQLAlchemy.</p>
<p>Download the example:  <a class="reference external" href="/files/2012/sqlalchemy_multiple_dbs.py">sqlalchemy_multiple_dbs.py</a></p>
</div>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://techspot.zzzeek.org</uri>
    </author>
    <title type="html"><![CDATA[Alembic Documentation Ready for Review]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2011/11/08/alembic-documentation-ready-for-review" />
    <id>http://techspot.zzzeek.org/2011/11/08/alembic-documentation-ready-for-review</id>
    <updated>2011-11-08T17:01:00Z</updated>
    <published>2011-11-08T17:01:00Z</published>
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <summary type="html"><![CDATA[Alembic Documentation Ready for Review]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2011/11/08/alembic-documentation-ready-for-review"><![CDATA[<div class="document">
<p>Many of you are aware that for quite some time I've had available a new migrations tool called
<a class="reference external" href="http://bitbucket.org/zzzeek/alembic">Alembic</a>.   I wrote the majority of this code last year
and basically haven't had much time to work on it, save for a little bit of integration at my day job.</p>
<p>Alembic has several areas that improve upon the current crop of migration tools, including:</p>
<ul class="simple">
<li>Full control over how migrations run, including multiple database support, transactional DDL, etc.</li>
<li>A super-minimal style of writing migrations, not requiring full table definitions for simple
operations.</li>
<li>No monkeypatching or repurposing of core SQLAlchemy objects.</li>
<li>Ability to generate migrations as SQL scripts, critical for working in large organizations
on restricted-access production systems.</li>
<li>A non-linear versioning model that allows, somewhat rudimentally, for branching and merging of
multiple migration file streams.</li>
<li>By popular request, designs for some degree of automation will be added, where &quot;obivous&quot; migrations
of tables or columns being added or dropped as well as simple column attribute changes can be detected
and rendered into migration scripts automatically.</li>
</ul>
<p>I get asked about migration tools quite often,  and I've always mentioned that I have such a tool
available in an early form, it just lacks documentation, hoping that one out of so many eager users
would be able to chip in a couple of days to help get it going.   Turns out it's simply not possible to
get someone to document your project for you; so here at the <a class="reference external" href="http://ploneconf.org">PloneConf</a> sprints I've taken
the time at the sprints to create initial documentation.  Originally I was going to do some work on
<a class="reference external" href="https://bitbucket.org/zzzeek/dogpile">Dogpile</a> but I've literally been asked about schema migrations,
either in person or via reddit or twitter, about nine times in the past three days.</p>
<p>The <a class="reference external" href="http://readthedocs.org/docs/alembic/en/latest/">documentation for Alembic</a> will provide an
overview of the tool, including theory of operation as well as philosophy, and some indicators of features not
yet implemented.   <strong>I would like feedback on the current approach.</strong>  Alembic is not yet released
though can be checked out from Bitbucket for testing.   It's a pretty simple tool, 1163 lines of code at the moment,
with plenty of room to support a lot more database features in a straightforward way.</p>
<p>I also have an open question about the notion of &quot;automatic&quot; migrations - how does one discern detecting
whether or not a table or column has had a name change, or if a new table/column was added and an old one
dropped?  Just a curiosity as I attempt to avoid reading South's source code.</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://techspot.zzzeek.org</uri>
    </author>
    <title type="html"><![CDATA[Value Agnostic Types, Part II]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2011/10/29/value-agnostic-types-part-ii" />
    <id>http://techspot.zzzeek.org/2011/10/29/value-agnostic-types-part-ii</id>
    <updated>2011-10-29T16:01:00Z</updated>
    <published>2011-10-29T16:01:00Z</published>
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <summary type="html"><![CDATA[Value Agnostic Types, Part II]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2011/10/29/value-agnostic-types-part-ii"><![CDATA[<div class="document">
<p>In <a class="reference external" href="/2011/10/21/hybrids-and-value-agnostic-types/">last week's post</a> I
illustrated how to use a &quot;value agnostic type&quot; in conjunction with an
ORM-mapped class, using the <tt class="docutils literal">&#64;hybrid_proprerty</tt> decorator.   Pressed for
details about the hypothetically better <tt class="docutils literal">TypeDecorator</tt> approach, we'll illustrate
that here.   The <tt class="docutils literal">TypeDecorator</tt> approach as I've mentioned has a few non-intuitive
edges, though after working out the example they're not so bad.  I do in fact
use the <tt class="docutils literal">TypeDecorator</tt> approach in my day job as often as I use the pure hybrid
approach.</p>
<div class="section" id="on-sql-objects-and-types">
<h1>On SQL Objects and Types</h1>
<p>The aspect of the approach I'm a little unsatisfied with is that SQLAlchemy
currently doesn't provide a first class pathway to linking operators
with the types they operate upon.   This is a situation I'd like to improve
in an upcoming release, but let's see what the general idea is.</p>
<p>SQLAlchemy separates the concerns of a &quot;SQL-representation&quot;
object and a &quot;type-representation&quot; object.   That is, when you deal with a <tt class="docutils literal">Column</tt>
associated with a table, it is distinct from its type:</p>


<div class="pygments_manni"><pre><span class="n">someint</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s">&#39;int_col&#39;</span><span class="p">,</span> <span class="n">Integer</span><span class="p">)</span>
<span class="n">somestring</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s">&#39;str_col&#39;</span><span class="p">,</span> <span class="n">String</span><span class="p">)</span>
</pre></div>



<p>where above, we have two <tt class="docutils literal">Column</tt> objects.  Each has a <tt class="docutils literal">type</tt> attribute, which
refers to the SQL type of the column.  Above,  these are illustrated as <tt class="docutils literal">Integer</tt> and <tt class="docutils literal">String</tt>.</p>
<p>I've seen other systems that do things more directly:</p>


<div class="pygments_manni"><pre><span class="n">someint</span> <span class="o">=</span> <span class="n">Integer</span><span class="p">(</span><span class="s">&quot;int_col&quot;</span><span class="p">)</span>
<span class="n">somestring</span> <span class="o">=</span> <span class="n">String</span><span class="p">(</span><span class="s">&quot;str_col&quot;</span><span class="p">)</span>
</pre></div>



<p>That approach is at first simpler, since you can now put special operators
upon <tt class="docutils literal">Integer</tt> and <tt class="docutils literal">String</tt> specific to those types, thereby linking
Python's typing behavior directly to that of the database.  However this fails
to model how the relational database actually works.  Suppose we derive new
SQL constructs from <tt class="docutils literal">someint</tt> and <tt class="docutils literal">somestring</tt>, a &quot;label&quot; and a &quot;scalar subquery&quot;,
respectively:</p>


<div class="pygments_manni"><pre><span class="n">label_of_someint</span> <span class="o">=</span> <span class="n">someint</span><span class="o">.</span><span class="n">label</span><span class="p">(</span><span class="s">&quot;some label&quot;</span><span class="p">)</span>
<span class="n">subquery</span> <span class="o">=</span> <span class="n">select</span><span class="p">([</span><span class="n">somestring</span><span class="p">])</span><span class="o">.</span><span class="n">as_scalar</span><span class="p">()</span>
</pre></div>



<p>Now what's the type-dependent behavior of those two
objects?  In this case, the rationale for SQLAlchemy's approach is clear - each has a <tt class="docutils literal">type</tt>
attribute copied straight from the origin expression, which applies the same
behavior to the derived construct as the original.  On the other hand, the &quot;expression-is-the-type&quot;
system would in theory require <tt class="docutils literal">IntegerLabel</tt>, <tt class="docutils literal">StringLabel</tt>, <tt class="docutils literal">IntegerSubquery</tt>, <tt class="docutils literal">StringSubquery</tt>
classes - an explosion of subclasses and behaviors awkwardly linked together.
Welding the datatype to the SQL expression type doesn't really work.</p>
<p>SQLAlchemy's approach is more comprehensive, but at the moment only has
limited hooks into the type when an expression is generated.   When an expression
is constructed, the type is consulted specifically for a few things, including
coercion of the operator, such as coercing the <tt class="docutils literal">add()</tt> operator to the <tt class="docutils literal">concat()</tt>
operator in the case of strings, as well as hints on what the return type
of the expression should be, and what kind of type the &quot;other&quot; side should be
treated as, if not already known.  It doesn't yet have a way to add new operators
to the SQL construct which contains the type, or to replace a value
with a SQL expression - something that would in particular help a lot with
things like PostGIS.   These problems are entirely solvable, however, and may occur
in a future release.</p>
<p>As it turns out, these limitations aren't terrible in the case of our <tt class="docutils literal">Amount</tt>
type, and we'll use the <a class="reference external" href="http://www.sqlalchemy.org/docs/core/types.html#augmenting-existing-types">TypeDecorator</a> to create
a new &quot;currency&quot; type that will work just as well without the ORM, that is with plain SQL expressions, as with it.  ORM-mapped classes no longer
will need to use <tt class="docutils literal">&#64;hybrid_property</tt> to coerce columns into the type.   And we'll even get <tt class="docutils literal">Amount</tt> objects back directly
in result sets.   Overall, after I tried this out, I realized it's definitely the better way to go.</p>
</div>
<div class="section" id="reintroducing-the-amount-type">
<h1>Reintroducing the Amount type</h1>
<p>We'll reuse the <tt class="docutils literal">Amount</tt> type from last week.   It's mostly the same,
except we'll remove <tt class="docutils literal">__clause_element__()</tt>, and additionally provide
a classmethod version of the <tt class="docutils literal">as_currency()</tt> method, which we'll use when
dealing with SQL expressions.  Because a SQLAlchemy custom type can't export
new operations to the enclosing SQL construct, special operations on currency types will be done via this
function called externally to the target, rather than a method call from the SQL expression construct itself:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">sqlalchemy.ext.hybrid</span> <span class="kn">import</span> <span class="n">hybrid_method</span>
<span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">type_coerce</span><span class="p">,</span> <span class="n">Numeric</span>

<span class="k">class</span> <span class="nc">Amount</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">amount</span><span class="p">,</span> <span class="n">currency</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">currency</span> <span class="o">=</span> <span class="n">currency</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">amount</span> <span class="o">=</span> <span class="n">amount</span>

    <span class="k">def</span> <span class="nf">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">Amount</span><span class="p">(</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">amount</span> <span class="o">+</span>
                <span class="n">other</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">)</span><span class="o">.</span><span class="n">amount</span><span class="p">,</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">currency</span>
            <span class="p">)</span>

    <span class="k">def</span> <span class="nf">__sub__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">Amount</span><span class="p">(</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">amount</span> <span class="o">-</span>
                <span class="n">other</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">)</span><span class="o">.</span><span class="n">amount</span><span class="p">,</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">currency</span>
            <span class="p">)</span>

    <span class="k">def</span> <span class="nf">__lt__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">amount</span> <span class="o">&lt;</span> <span class="n">other</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">)</span><span class="o">.</span><span class="n">amount</span>

    <span class="k">def</span> <span class="nf">__gt__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">amount</span> <span class="o">&gt;</span> <span class="n">other</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">)</span><span class="o">.</span><span class="n">amount</span>

    <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">amount</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">)</span><span class="o">.</span><span class="n">amount</span>

    <span class="nd">@hybrid_method</span>
    <span class="k">def</span> <span class="nf">as_currency</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other_currency</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">Amount</span><span class="p">(</span>
                    <span class="n">currency_lookup</span><span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">,</span> <span class="n">other_currency</span><span class="p">)]</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">amount</span><span class="p">,</span>
                    <span class="n">other_currency</span><span class="p">)</span>

    <span class="nd">@as_currency.expression</span>
    <span class="k">def</span> <span class="nf">as_currency</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="n">other_currency</span><span class="p">):</span>
        <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="s">&#39;__clause_element__&#39;</span><span class="p">):</span>
            <span class="n">target</span> <span class="o">=</span> <span class="n">target</span><span class="o">.</span><span class="n">__clause_element__</span><span class="p">()</span>
        <span class="n">currency</span> <span class="o">=</span> <span class="n">target</span><span class="o">.</span><span class="n">type</span><span class="o">.</span><span class="n">currency</span>
        <span class="k">return</span> <span class="n">Amount</span><span class="p">(</span>
                    <span class="n">currency_lookup</span><span class="p">[(</span><span class="n">currency</span><span class="p">,</span> <span class="n">other_currency</span><span class="p">)]</span>
                     <span class="o">*</span> <span class="n">type_coerce</span><span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">Numeric</span><span class="p">),</span>
                    <span class="n">other_currency</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;</span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">amount</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;Amount(</span><span class="si">%s</span><span class="s">)&quot;</span> <span class="o">%</span> <span class="bp">self</span>
</pre></div>



<p>The basic thing we've added above is a class level version of <tt class="docutils literal">as_currency()</tt>, which accepts a target and a currency.
This would be used like:</p>


<div class="pygments_manni"><pre><span class="n">Amount</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="n">mytable</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">balance</span><span class="p">,</span> <span class="s">&quot;usd&quot;</span><span class="p">)</span>
</pre></div>



<p>This method needs to take a peek at what it gets to see if it's directly a SQL expression,
or an ORM-oriented expression that needs the <tt class="docutils literal">__clause_element__()</tt> method to resolve
down to the SQL expression.  Consider this to be &quot;rough edge&quot; number one, if you will,
though there's not much to it.</p>
<p>Another special step in that method is that we're using <tt class="docutils literal">type_coerce(value, Numeric)</tt> to
coerce the <tt class="docutils literal">target</tt>, which will be a SQL expression using our new <tt class="docutils literal">TypeDecorator</tt>, so that it's treated as a
<tt class="docutils literal">Numeric</tt> when multiplying by the exchange rate. If we didn't
do that, the type coercion rule used by our type would take effect and assume the
exchange rate is also an <tt class="docutils literal">Amount</tt> type, which is not the case.  While that
coercion rule can be customized to handle an incoming <tt class="docutils literal">Decimal</tt> value,
it's more appropriately left as is, since expressions against <tt class="docutils literal">Amount</tt> should always
be using another <tt class="docutils literal">Amount</tt> object.</p>
<p>Oddly enough we used <tt class="docutils literal">&#64;hybrid_method</tt> to provide the &quot;dual purposed&quot; behavior of <tt class="docutils literal">as_currency()</tt>
at the instance level and at the class level.  Nothing to do with the ORM here, just a handy
place to use it.</p>
<p>Our <tt class="docutils literal">TypeDecorator</tt> is then pretty much from the docs:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">TypeDecorator</span><span class="p">,</span> <span class="n">Numeric</span>

<span class="k">class</span> <span class="nc">AmountType</span><span class="p">(</span><span class="n">TypeDecorator</span><span class="p">):</span>
    <span class="n">impl</span> <span class="o">=</span> <span class="n">Numeric</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">currency</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">currency</span> <span class="o">=</span> <span class="n">currency</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">AmountType</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">process_bind_param</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">dialect</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
            <span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">)</span><span class="o">.</span><span class="n">amount</span>
        <span class="k">return</span> <span class="n">value</span>

    <span class="k">def</span> <span class="nf">process_result_value</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">dialect</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
            <span class="n">value</span> <span class="o">=</span> <span class="n">Amount</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">value</span>
</pre></div>



<p>Now if we modify our mapping from last week, we can take out the hybrid, and
just use <tt class="docutils literal">AmountType</tt> directly:</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">BankAccount</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;bank_account&#39;</span>
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>

    <span class="n">balance</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s">&#39;balance&#39;</span><span class="p">,</span> <span class="n">AmountType</span><span class="p">(</span><span class="s">&quot;usd&quot;</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;BankAccount(</span><span class="si">%s</span><span class="s">)&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">balance</span>
</pre></div>



<p>And that's it !   What changes with this usage, and what stays the same ?
Most simple things stay the same, such as creating new <tt class="docutils literal">BankAccount</tt> objects:</p>


<div class="pygments_manni"><pre><span class="n">session</span><span class="o">.</span><span class="n">add_all</span><span class="p">([</span>
    <span class="n">account</span><span class="p">,</span>
    <span class="n">BankAccount</span><span class="p">(</span><span class="n">balance</span><span class="o">=</span><span class="n">Amount</span><span class="p">(</span><span class="mi">10000</span><span class="p">,</span> <span class="s">&quot;cad&quot;</span><span class="p">)),</span>
    <span class="n">BankAccount</span><span class="p">(</span><span class="n">balance</span><span class="o">=</span><span class="n">Amount</span><span class="p">(</span><span class="mi">5700</span><span class="p">,</span> <span class="s">&quot;usd&quot;</span><span class="p">)),</span>
    <span class="n">BankAccount</span><span class="p">(</span><span class="n">balance</span><span class="o">=</span><span class="n">Amount</span><span class="p">(</span><span class="mi">89682</span><span class="p">,</span> <span class="s">&quot;aud&quot;</span><span class="p">)),</span>
<span class="p">])</span>
</pre></div>



<p>as well as basic comparison operations:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">BankAccount</span><span class="p">)</span><span class="o">.</span>\
<span class="gp">... </span>   <span class="nb">filter</span><span class="p">(</span><span class="n">BankAccount</span><span class="o">.</span><span class="n">balance</span> <span class="o">==</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">10000</span><span class="p">,</span> <span class="s">&quot;cad&quot;</span><span class="p">))</span><span class="o">.</span><span class="n">one</span><span class="p">()</span>
<span class="go">SELECT bank_account.id AS bank_account_id,</span>
<span class="go">        bank_account.balance AS bank_account_balance</span>
<span class="go">FROM bank_account</span>
<span class="go">WHERE bank_account.balance = ?</span>
<span class="go">(9886.11,)</span>
<span class="go">BankAccount(9886.1100 usd)</span>
</pre></div>



<p>A change is when we want to use an <tt class="docutils literal">Amount</tt> specific operator on the
SQL side, namely <tt class="docutils literal">as_currency()</tt>.  We use the new class-level version,
which produces a new <tt class="docutils literal">Amount</tt> object given against the underlying
<tt class="docutils literal">balance</tt> column, coerced into a <tt class="docutils literal">Numeric</tt> and multiplied by
the exchange rate:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">Amount</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="n">BankAccount</span><span class="o">.</span><span class="n">balance</span><span class="p">,</span> <span class="s">&quot;cad&quot;</span><span class="p">)</span>
<span class="go">:param_1 * bank_account.balance cad</span>
</pre></div>



<p>In other words, &quot;(exchange rate * numeric balance) in canadian dollars&quot;.  The returned
<tt class="docutils literal">Amount</tt> object maintains the &quot;hybrid&quot; behavior we saw last week:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">BankAccount</span><span class="p">)</span><span class="o">.</span>\
<span class="gp">... </span>   <span class="nb">filter</span><span class="p">(</span><span class="n">Amount</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="n">BankAccount</span><span class="o">.</span><span class="n">balance</span><span class="p">,</span> <span class="s">&quot;cad&quot;</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">9999</span><span class="p">,</span> <span class="s">&quot;cad&quot;</span><span class="p">))</span><span class="o">.</span>\
<span class="gp">... </span>   <span class="nb">filter</span><span class="p">(</span><span class="n">Amount</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="n">BankAccount</span><span class="o">.</span><span class="n">balance</span><span class="p">,</span> <span class="s">&quot;cad&quot;</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">10001</span><span class="p">,</span> <span class="s">&quot;cad&quot;</span><span class="p">))</span><span class="o">.</span>\
<span class="gp">... </span>   <span class="n">one</span><span class="p">()</span>
<span class="go">SELECT bank_account.id AS bank_account_id, bank_account.balance AS bank_account_balance</span>
<span class="go">FROM bank_account</span>
<span class="go">WHERE ? * bank_account.balance &gt; ? AND ? * bank_account.balance &lt; ?</span>
<span class="go">(1.01152, 9999.0, 1.01152, 10001.0)</span>
<span class="go">BankAccount(9886.1100 usd)</span>
</pre></div>



<p>With the typed approach, we can finally get <tt class="docutils literal">Amount</tt> objects straight back from a result
set:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">BankAccount</span><span class="o">.</span><span class="n">balance</span><span class="p">)</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="go">SELECT bank_account.balance AS bank_account_balance FROM bank_account</span>
<span class="go">[(Amount(4000.0000 usd),), (Amount(9886.1100 usd),), (Amount(5700.0000 usd),), (Amount(92338.3808 usd),)]</span>
</pre></div>



<p>and it works without the ORM too !</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">select</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">bank_account</span> <span class="o">=</span> <span class="n">BankAccount</span><span class="o">.</span><span class="n">__table__</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">for</span> <span class="n">amount</span><span class="p">,</span> <span class="ow">in</span> <span class="n">session</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
<span class="gp">... </span>           <span class="n">select</span><span class="p">([</span><span class="n">bank_account</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">balance</span><span class="p">])</span><span class="o">.</span>\
<span class="gp">... </span>           <span class="n">where</span><span class="p">(</span><span class="n">Amount</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="n">bank_account</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">balance</span><span class="p">,</span> <span class="s">&quot;cad&quot;</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">9999</span><span class="p">,</span> <span class="s">&quot;cad&quot;</span><span class="p">))</span>
<span class="gp">... </span>           <span class="p">)</span><span class="o">.</span><span class="n">fetchall</span><span class="p">():</span>
<span class="gp">... </span>    <span class="k">print</span> <span class="s">&quot;Amount:&quot;</span><span class="p">,</span> <span class="n">amount</span><span class="p">,</span> \
<span class="gp">... </span>                <span class="s">&quot;As USD:&quot;</span><span class="p">,</span> <span class="n">amount</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="s">&quot;usd&quot;</span><span class="p">),</span> \
<span class="gp">... </span>                <span class="s">&quot;As CAD:&quot;</span><span class="p">,</span> <span class="n">amount</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="s">&quot;cad&quot;</span><span class="p">)</span>
<span class="go">SELECT bank_account.balance FROM bank_account</span>
<span class="go">WHERE ? * bank_account.balance &gt; ?</span>
<span class="go">(1.01152, 9999.0)</span>
<span class="go">Amount: 9886.1100 usd As USD: 9886.1100 usd As CAD: 9999.9980 cad</span>
<span class="go">Amount: 92338.3808 usd As USD: 92338.3808 usd As CAD: 93402.1190 cad</span>
</pre></div>



</div>
<div class="section" id="downloads">
<h1>Downloads</h1>
<p>Download the revised version of <tt class="docutils literal">account_currency.py</tt>:</p>
<ul class="simple">
<li><a class="reference external" href="/files/2011/account_currency_typedec.py">account_currency_typedec.py</a></li>
</ul>
</div>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://techspot.zzzeek.org</uri>
    </author>
    <title type="html"><![CDATA[Hybrids and Value Agnostic Types]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2011/10/21/hybrids-and-value-agnostic-types" />
    <id>http://techspot.zzzeek.org/2011/10/21/hybrids-and-value-agnostic-types</id>
    <updated>2011-10-21T16:01:00Z</updated>
    <published>2011-10-21T16:01:00Z</published>
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <summary type="html"><![CDATA[Hybrids and Value Agnostic Types]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2011/10/21/hybrids-and-value-agnostic-types"><![CDATA[<div class="document">
<p><strong>Update:</strong> This is now part one of a two part series. Be sure to read <a class="reference external" href="/2011/10/29/value-agnostic-types-part-ii/">Value
Agnostic Types, Part II</a> for an
updated approach using <tt class="docutils literal">TypeDecorator</tt>.</p>
<p>A &quot;hybrid&quot; in SQLAlchemy is this awesome idea thought up by Ants Aasma.  The hybrid takes advantage
of the ability of Python classes to have an attribute which has customizable behavior
both at the class level as well as at the instance level.  What's that mean?  Just this:</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">my_descriptor</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__get__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">owner</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">instance</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
            <span class="k">return</span> <span class="s">&quot;I&#39;m at the class level!&quot;</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="s">&quot;I&#39;m at the instance level!&quot;</span>

<span class="k">class</span> <span class="nc">MyClass</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="n">some_attribute</span> <span class="o">=</span> <span class="n">my_descriptor</span><span class="p">()</span>
</pre></div>



<p>Above, <tt class="docutils literal">my_descriptor</tt> is what's known as a <a class="reference external" href="http://docs.python.org/reference/datamodel.html#descriptor-invocation">Python Descriptor</a>.  It's a way
to have an attribute on an object where the value produced comes from a function.  Above, we've made one that will tell you one thing when
invoked on the class, i.e. <em>class level</em> behavior:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">MyClass</span><span class="o">.</span><span class="n">some_attribute</span>
<span class="go">I&#39;m at the class level!</span>
</pre></div>



<p>And another at the instance level, i.e. <em>instance level</em> behavior:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">my_object</span> <span class="o">=</span> <span class="n">MyClass</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">my_object</span><span class="o">.</span><span class="n">some_attribute</span>
<span class="go">I&#39;m at the instance level!</span>
</pre></div>



<p>That's all we're dealing with here.  As it turns out, descriptors are very commonly used in object relational mappers
and other &quot;declarative&quot; kinds of systems, where attributes are defined at the class level and maintain
behavior on the class, as well as on instances.   Suppose we have a SQLAlchemy class like this:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span> <span class="n">declarative_base</span>
<span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">Column</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">Numeric</span>
<span class="n">Base</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">BankAccount</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;bank_account&#39;</span>
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>

    <span class="n">balance</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Numeric</span><span class="p">)</span>
    <span class="n">pending</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Numeric</span><span class="p">)</span>
</pre></div>



<p>We've made a new class <tt class="docutils literal">BankAccount</tt>, which represents something like a bank account.
It contains fields representing the current account balance, as well as a
&quot;pending&quot; balance - say it's checks that haven't cleared yet.</p>
<p>Let's set up a sqlite database as usual and save some accounts:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">create_engine</span>
<span class="n">engine</span> <span class="o">=</span> <span class="n">create_engine</span><span class="p">(</span><span class="s">&#39;sqlite://&#39;</span><span class="p">,</span> <span class="n">echo</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">Base</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">create_all</span><span class="p">(</span><span class="n">engine</span><span class="p">)</span>

<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="n">Session</span>
<span class="n">session</span> <span class="o">=</span> <span class="n">Session</span><span class="p">(</span><span class="n">engine</span><span class="p">)</span>
<span class="n">session</span><span class="o">.</span><span class="n">add_all</span><span class="p">([</span>
    <span class="n">BankAccount</span><span class="p">(</span><span class="n">balance</span><span class="o">=</span><span class="mi">4000</span><span class="p">,</span> <span class="n">pending</span><span class="o">=</span><span class="mi">500</span><span class="p">),</span>
    <span class="n">BankAccount</span><span class="p">(</span><span class="n">balance</span><span class="o">=</span><span class="mi">10000</span><span class="p">,</span> <span class="n">pending</span><span class="o">=</span><span class="mi">0</span><span class="p">),</span>
<span class="p">])</span>
<span class="n">session</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
</pre></div>



<p>Descriptors are used here as follows: first, the <tt class="docutils literal">BankAccount</tt> class, as a result
of being mapped by SQLAlchemy, has three
descriptors on it, named <tt class="docutils literal">id</tt>, <tt class="docutils literal">balance</tt>, and <tt class="docutils literal">pending</tt>.  These descriptors
have class- and instance-level behavior.
When invoked at the class level, they produce SQL expressions:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">BankAccount</span><span class="o">.</span><span class="n">balance</span> <span class="o">+</span> <span class="n">BankAccount</span><span class="o">.</span><span class="n">pending</span>
<span class="go">balance + pending</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">select</span><span class="p">([</span><span class="n">BankAccount</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">BankAccount</span><span class="o">.</span><span class="n">balance</span><span class="p">])</span>
<span class="go">SELECT id, balance FROM bank_account</span>
</pre></div>



<p>Invoked at the instance level, they provide access to values that are present in <tt class="docutils literal">__dict__</tt>,
the same way any other Python object works:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">account</span> <span class="o">=</span> <span class="n">BankAccount</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">account</span><span class="o">.</span><span class="n">balance</span> <span class="o">=</span> <span class="mi">1000</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">account</span><span class="o">.</span><span class="n">pending</span> <span class="o">=</span> <span class="mi">500</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">account</span><span class="o">.</span><span class="n">__dict__</span>
<span class="go">{&#39;balance&#39;: 1000, &#39;pending&#39;: 500, &#39;_sa_instance_state&#39;: &lt;sqlalchemy.orm.state.InstanceState object at 0x1014dde50&gt;}</span>
</pre></div>



<p>(<tt class="docutils literal">_sa_instance_state</tt> is SQLAlchemy's tracking object for this particular <tt class="docutils literal">BankAccount</tt>).  SQLAlchemy's descriptors,
used at the instance level, also keep track of changes to data, and can also invoke queries
against the database to load more data if needed.</p>
<div class="section" id="taking-advantage-of-the-descriptor-with-a-hybrid">
<h1>Taking Advantage of the Descriptor with a Hybrid</h1>
<p>The main thing to understand about the previous section is that the attributes of <tt class="docutils literal">BankAccount</tt>,
that is <tt class="docutils literal">id</tt>, <tt class="docutils literal">balance</tt>, and <tt class="docutils literal">pending</tt>, are ultimately powered by Python functions, which work
both on an instance as well as on a class.  The first argument passed to these functions is either
<tt class="docutils literal">self</tt>, that is, an instance of <tt class="docutils literal">BankAccount</tt>, or <tt class="docutils literal">cls</tt>, that is, the <tt class="docutils literal">BankAccount</tt> class itself.
Both <tt class="docutils literal">self</tt> and <tt class="docutils literal">cls</tt> have <em>the same</em> attributes present on them, and in many ways can be treated
identically; we often don't have to <em>care</em> that we're dealing with <tt class="docutils literal">self</tt> or <tt class="docutils literal">cls</tt>.
Hybrids take advantage of this symmetry and allow us to expand upon it.   The core idea of the Hybrid is
not as much a SQLAlchemy thing as it is a general Python thing - you can use the same idea with most
other ORMs that feature usage of descriptors in this way.</p>
<p>To illustrate, let's give our <tt class="docutils literal">BankAccount</tt> class a new data member called <tt class="docutils literal">total</tt>, representing
the balance amount plus the pending amount.   When we have a <tt class="docutils literal">BankAccount</tt>
loaded in memory, this is simple addition of the existing values,  and there's no need
to go out to the database for this.  We'll use the well known Python descriptor helper called
<a class="reference external" href="http://docs.python.org/library/functions.html#property">&#64;property</a> so that we can say <tt class="docutils literal">myaccount.total</tt>
as though it were a regular attribute:</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">BankAccount</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;bank_account&#39;</span>
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>

    <span class="n">balance</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Numeric</span><span class="p">)</span>
    <span class="n">pending</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Numeric</span><span class="p">)</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">total</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">balance</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending</span>
</pre></div>



<p>With the above, we can get the total amount present in an account:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">BankAccount</span><span class="p">(</span><span class="n">balance</span><span class="o">=</span><span class="mi">1000</span><span class="p">,</span> <span class="n">pending</span><span class="o">=</span><span class="mi">500</span><span class="p">)</span><span class="o">.</span><span class="n">total</span>
<span class="go">1500</span>
</pre></div>



<p>Simple enough.  But the hybrid can add a new twist to the above, which is that we can transparently
calculate the area over on the <em>database</em> side as well.  The expression we have:</p>


<div class="pygments_manni"><pre><span class="bp">self</span><span class="o">.</span><span class="n">balance</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending</span>
</pre></div>



<p>can be written against the <tt class="docutils literal">BankAccount</tt> class, using a query, like this:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">BankAccount</span><span class="o">.</span><span class="n">balance</span> <span class="o">+</span> <span class="n">BankAccount</span><span class="o">.</span><span class="n">pending</span><span class="p">)</span>
<span class="go">SELECT bank_account.balance + bank_account.pending AS anon_1</span>
<span class="go">FROM bank_account</span>
</pre></div>



<p>The hybrid provides a single descriptor that can emit either an expression against the instance,
or against the class, where <tt class="docutils literal">self</tt> might
be either an instance of <tt class="docutils literal">BankAccount</tt>, or the <tt class="docutils literal">BankAccount</tt> class:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">sqlalchemy.ext.hybrid</span> <span class="kn">import</span> <span class="n">hybrid_property</span>

<span class="k">class</span> <span class="nc">BankAccount</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;bank_account&#39;</span>
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>

    <span class="n">balance</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Numeric</span><span class="p">)</span>
    <span class="n">pending</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Numeric</span><span class="p">)</span>

    <span class="nd">@hybrid_property</span>
    <span class="k">def</span> <span class="nf">total</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">balance</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">pending</span>
</pre></div>



<p>So we can now do this:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">BankAccount</span><span class="o">.</span><span class="n">total</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">BankAccount</span><span class="o">.</span><span class="n">total</span><span class="o">.</span><span class="n">between</span><span class="p">(</span><span class="mi">3000</span><span class="p">,</span> <span class="mi">5000</span><span class="p">))</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="go">SELECT bank_account.balance + bank_account.pending AS anon_1</span>
<span class="go">FROM bank_account</span>
<span class="go">WHERE bank_account.balance + bank_account.pending BETWEEN ? AND ?</span>
<span class="go">(3000, 5000)</span>
<span class="go">[(Decimal(&#39;4500.0000000000&#39;),)]</span>
</pre></div>



<p>We can see that the <tt class="docutils literal">total</tt> attribute works at the SQL level by emitting a SQL expression,
at the instance level like a regular <tt class="docutils literal">&#64;property</tt>:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">myaccount</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">BankAccount</span><span class="p">)</span><span class="o">.</span><span class="n">first</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">myaccount</span><span class="o">.</span><span class="n">total</span>
<span class="go">4500.0000000000</span>
</pre></div>



<p>While this is a simple example, hybrids have more options for real world cases, particularly
the very common case that the SQL expression needs to be defined separately.  That,
and everything else hybrids can do, are described fully in the document
<a class="reference external" href="http://www.sqlalchemy.org/docs/orm/extensions/hybrid.html">Hybrid Attributes</a> on the SQLAlchemy site.</p>
</div>
<div class="section" id="value-agnostic-types">
<h1>Value Agnostic Types</h1>
<p>Now to introduce a variant on this technique which is <em>not</em> in the docs.   The
behavior of the hybrid will be offloaded into a new type that's generally not SQLAlchemy specific.
We'll apply the technique towards the problem of representing a monetary amount in a currency-agnostic
fashion, where exchange rates can be applied relatively transparently.   We'll
introduce first how we'll work with amounts and exchange rates, starting with a simple lookup
dictionary of rates:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">decimal</span> <span class="kn">import</span> <span class="n">Decimal</span>

<span class="c"># US dollars, British pounds, Canadian dollar, Euro, Australian dollar</span>
<span class="n">symbols</span> <span class="o">=</span> <span class="p">(</span><span class="s">&#39;usd&#39;</span><span class="p">,</span> <span class="s">&#39;gbp&#39;</span><span class="p">,</span> <span class="s">&#39;cad&#39;</span><span class="p">,</span> <span class="s">&#39;eur&#39;</span><span class="p">,</span> <span class="s">&#39;aud&#39;</span><span class="p">)</span>
<span class="n">currency_lookup</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span>
            <span class="p">((</span><span class="n">currency_from</span><span class="p">,</span> <span class="n">currency_to</span><span class="p">),</span> <span class="n">Decimal</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">rate</span><span class="p">)))</span>
            <span class="k">for</span> <span class="n">currency_to</span><span class="p">,</span> <span class="n">values</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span>
                <span class="n">symbols</span><span class="p">,</span>
                <span class="p">[</span>
                    <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mf">1.59009</span><span class="p">,</span> <span class="mf">0.988611</span><span class="p">,</span> <span class="mf">1.37979</span><span class="p">,</span> <span class="mf">1.02962</span><span class="p">),</span>
                    <span class="p">(</span><span class="mf">0.628895</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mf">0.621732</span><span class="p">,</span> <span class="mf">0.867748</span><span class="p">,</span> <span class="mf">0.647525</span><span class="p">),</span>
                    <span class="p">(</span><span class="mf">1.01152</span><span class="p">,</span> <span class="mf">1.6084</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mf">1.39569</span><span class="p">,</span> <span class="mf">1.04148</span><span class="p">),</span>
                    <span class="p">(</span><span class="mf">0.724743</span><span class="p">,</span> <span class="mf">1.1524</span><span class="p">,</span> <span class="mf">0.716489</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mf">0.746213</span><span class="p">),</span>
                    <span class="p">(</span><span class="mf">0.971228</span><span class="p">,</span> <span class="mf">1.54434</span><span class="p">,</span> <span class="mf">0.960166</span><span class="p">,</span> <span class="mf">1.34009</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span>
                <span class="p">])</span>
            <span class="k">for</span> <span class="n">currency_from</span><span class="p">,</span> <span class="n">rate</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">symbols</span><span class="p">,</span> <span class="n">values</span><span class="p">)</span>
    <span class="p">)</span>
</pre></div>



<p>The above creates a dictionary <tt class="docutils literal">currency_lookup</tt> which contains exchange rates between
pairs of symbols.  If we had the value of 5000 in US dollars (USD), and wanted to
convert to Australian dollars (AUD), we'd look up the key (&quot;usd&quot;, &quot;aud&quot;) in the dictionary,
giving us a rate to multiply by 5000:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">currency_lookup</span><span class="p">[(</span><span class="s">&quot;usd&quot;</span><span class="p">,</span> <span class="s">&quot;aud&quot;</span><span class="p">)]</span> <span class="o">*</span> <span class="mi">5000</span>
<span class="go">4856.140000</span>
</pre></div>



<p>Next we'll build an interface for this dictionary, an <tt class="docutils literal">Amount</tt> object that represents
the combination of a monetary amount, and a particular currency symbol.  The <tt class="docutils literal">Amount</tt>
object acts like a numeric value, but intercepts Python math and comparison operations
to first coerce the &quot;right&quot; side of an equation to use the same currency as the &quot;left&quot;
side:</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">Amount</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">amount</span><span class="p">,</span> <span class="n">currency</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">currency</span> <span class="o">=</span> <span class="n">currency</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">amount</span> <span class="o">=</span> <span class="n">amount</span>

    <span class="k">def</span> <span class="nf">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">Amount</span><span class="p">(</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">amount</span> <span class="o">+</span>
                <span class="n">other</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">)</span><span class="o">.</span><span class="n">amount</span><span class="p">,</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">currency</span>
            <span class="p">)</span>

    <span class="k">def</span> <span class="nf">__sub__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">Amount</span><span class="p">(</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">amount</span> <span class="o">-</span>
                <span class="n">other</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">)</span><span class="o">.</span><span class="n">amount</span><span class="p">,</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">currency</span>
            <span class="p">)</span>

    <span class="k">def</span> <span class="nf">__lt__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">amount</span> <span class="o">&lt;</span> <span class="n">other</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">)</span><span class="o">.</span><span class="n">amount</span>

    <span class="k">def</span> <span class="nf">__gt__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">amount</span> <span class="o">&gt;</span> <span class="n">other</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">)</span><span class="o">.</span><span class="n">amount</span>

    <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">amount</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">)</span><span class="o">.</span><span class="n">amount</span>

    <span class="k">def</span> <span class="nf">as_currency</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other_currency</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">Amount</span><span class="p">(</span>
                    <span class="n">currency_lookup</span><span class="p">[(</span><span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">,</span> <span class="n">other_currency</span><span class="p">)]</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">amount</span><span class="p">,</span>
                    <span class="n">other_currency</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;</span><span class="si">%2.4f</span><span class="s"> </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">amount</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">currency</span><span class="p">)</span>
</pre></div>



<p>Above, while we have only implemented a small set of Python comparison and math operations,
the <tt class="docutils literal">Amount</tt> implementation above can handle addition, subtraction, the equals operator, and the
less than/greater than operations.  All coercion is via a single method <tt class="docutils literal">as_currency()</tt>
which just looks up the exchange rate in the <tt class="docutils literal">currency_lookup</tt> table, and converts the &quot;other&quot;
side of any equation into a new <tt class="docutils literal">Amount</tt> that is against the source currency:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="c"># Convert 5000 US dollars into Canadian dollars</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">5000</span><span class="p">,</span> <span class="s">&quot;usd&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="s">&quot;cad&quot;</span><span class="p">)</span>
<span class="go">5057.6000 cad</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c"># Calculate 5000 USD + 1000 USD:</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">5000</span><span class="p">,</span> <span class="s">&quot;usd&quot;</span><span class="p">)</span> <span class="o">+</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">1000</span><span class="p">,</span> <span class="s">&quot;usd&quot;</span><span class="p">)</span>
<span class="go">6000.000 usd</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c"># Calculate 5000 USD + 500 GBP:</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">5000</span><span class="p">,</span> <span class="s">&quot;usd&quot;</span><span class="p">)</span> <span class="o">+</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">500</span><span class="p">,</span> <span class="s">&quot;gbp&quot;</span><span class="p">)</span>
<span class="go">5795.0450 usd</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c"># Take the above and convert to CAD:</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="p">(</span><span class="n">Amount</span><span class="p">(</span><span class="mi">5000</span><span class="p">,</span> <span class="s">&quot;usd&quot;</span><span class="p">)</span> <span class="o">+</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">500</span><span class="p">,</span> <span class="s">&quot;gbp&quot;</span><span class="p">))</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="s">&quot;cad&quot;</span><span class="p">)</span>
<span class="go">5861.8039 cad</span>
</pre></div>



<p>The thing to keep in mind going forward is that, while we're about to do something
more interesting with our <tt class="docutils literal">Amount</tt> class, it will always be used as an instance
of an <tt class="docutils literal">Amount</tt> - we're not going to map this class at all.  What we're instead going
to do is take advantage of the hybrid approach and apply it to the argument we pass to
<tt class="docutils literal">Amount</tt>.  Suppose we passed a SQLAlchemy expression construct to <tt class="docutils literal">Amount</tt>, instead of
a numeric value.  What would happen ?</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">sqlalchemy.sql</span> <span class="kn">import</span> <span class="n">column</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">balance_col</span> <span class="o">=</span> <span class="n">column</span><span class="p">(</span><span class="s">&#39;balance&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">Amount</span><span class="p">(</span><span class="n">balance_col</span><span class="p">,</span> <span class="s">&quot;aud&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="s">&quot;eur&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">amount</span>
<span class="go">:balance_1 * balance</span>
</pre></div>



<p>Passing in a <tt class="docutils literal">sqlalchemy.sql.column</tt> object to <tt class="docutils literal">Amount</tt> instead of a numeric value,
we got a SQL expression straight
out of the <tt class="docutils literal">Amount</tt> object, which itself had no idea it wasn't handling a number.  Note
we needed to access <tt class="docutils literal">.amount</tt> in order to display it, as the expression would not have
made it through our number formatting <tt class="docutils literal">Amount.__str__()</tt> method.   But otherwise, we can pass
any type of object into <tt class="docutils literal">Amount</tt> which accommodates basic calculations and it will
work fine.</p>
</div>
<div class="section" id="mapping-with-value-agnostic-types">
<h1>Mapping with Value Agnostic Types</h1>
<p>To apply the above <tt class="docutils literal">Amount</tt> object to a mapping, we'll again go back to hybrids.   The technique
we'll show here uses the object model to coerce between <tt class="docutils literal">Amount</tt> and a raw numeric value.
Another option is to use custom types via <tt class="docutils literal">TypeDecorator</tt> - this is detailed in the next
post, <a class="reference external" href="/2011/10/29/value-agnostic-types-part-ii/">Value Agnostic Types, Part II</a>.
A great advantage of using a hybrid with the value agnostic type is that the whole thing
is almost totally orthogonal to SQLAlchemy itself, with very few moving parts or library
dependencies.</p>
<p>Let's start up a new <tt class="docutils literal">BankAccount</tt> class, this time the <tt class="docutils literal">BankAccount</tt> will specifically be an account
that stores funds in US dollars.   We'll store just a balance for now, and the public interface for
the balance will be via the <tt class="docutils literal">Amount</tt> object:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span> <span class="n">declarative_base</span>
<span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">Column</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">Numeric</span>
<span class="kn">from</span> <span class="nn">sqlalchemy.ext.hybrid</span> <span class="kn">import</span> <span class="n">hybrid_property</span>
<span class="n">Base</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">BankAccount</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;bank_account&#39;</span>
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>

    <span class="n">_balance</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="s">&#39;balance&#39;</span><span class="p">,</span> <span class="n">Numeric</span><span class="p">)</span>

    <span class="nd">@hybrid_property</span>
    <span class="k">def</span> <span class="nf">balance</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">Amount</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_balance</span><span class="p">,</span> <span class="s">&quot;usd&quot;</span><span class="p">)</span>

    <span class="nd">@balance.setter</span>
    <span class="k">def</span> <span class="nf">balance</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_balance</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="s">&quot;usd&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">amount</span>

    <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;BankAccount(</span><span class="si">%s</span><span class="s">)&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">balance</span>
</pre></div>



<p>The <tt class="docutils literal">balance</tt> column is applied to a private attribute <tt class="docutils literal">_balance</tt>, and the public accessor <tt class="docutils literal">balance</tt>
uses a hybrid to coerce to/from an <tt class="docutils literal">Amount</tt> object, hardcoding &quot;usd&quot; as the base exchange currency.
Given a new <tt class="docutils literal">BankAccount</tt>, we can operate on &quot;balance&quot;
at the Python level, using <tt class="docutils literal">Amount</tt> objects as value objects:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">account</span> <span class="o">=</span> <span class="n">BankAccount</span><span class="p">(</span><span class="n">balance</span><span class="o">=</span><span class="n">Amount</span><span class="p">(</span><span class="mi">4000</span><span class="p">,</span> <span class="s">&quot;usd&quot;</span><span class="p">))</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">account</span><span class="o">.</span><span class="n">balance</span>
<span class="go">4000.0000 usd</span>

<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">account</span><span class="o">.</span><span class="n">balance</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="s">&quot;gbp&quot;</span><span class="p">)</span>
<span class="go">2515.5800 gbp</span>

<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">account</span><span class="o">.</span><span class="n">balance</span> <span class="o">&gt;</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">500</span><span class="p">,</span> <span class="s">&quot;cad&quot;</span><span class="p">)</span>
<span class="go">True</span>

<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">account</span><span class="o">.</span><span class="n">balance</span> <span class="o">+</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">500</span><span class="p">,</span> <span class="s">&quot;cad&quot;</span><span class="p">)</span> <span class="o">-</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="s">&quot;eur&quot;</span><span class="p">)</span>
<span class="go">4425.3160 usd</span>
</pre></div>



<p>All we're doing here is accessing the <tt class="docutils literal">.balance</tt> attribute on an instance of <tt class="docutils literal">BankAccount</tt>,
where the <tt class="docutils literal">Amount</tt> instance returned acts against the underlying value.</p>
<p>But note we've applied <tt class="docutils literal">&#64;hybrid_property</tt> to <tt class="docutils literal">.balance</tt>.  That means we want to use it
as a SQL expression too.   Used in a SQL context, it returns the same <tt class="docutils literal">Amount</tt> object,
passing in the <tt class="docutils literal">._balance</tt> <tt class="docutils literal">Column</tt> object, working as it did earlier.  Starting
with some test data:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">create_engine</span>
<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="n">Session</span>
<span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">func</span>

<span class="n">engine</span> <span class="o">=</span> <span class="n">create_engine</span><span class="p">(</span><span class="s">&#39;sqlite://&#39;</span><span class="p">,</span> <span class="n">echo</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
<span class="n">Base</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">create_all</span><span class="p">(</span><span class="n">engine</span><span class="p">)</span>

<span class="n">session</span> <span class="o">=</span> <span class="n">Session</span><span class="p">(</span><span class="n">engine</span><span class="p">)</span>

<span class="n">session</span><span class="o">.</span><span class="n">add_all</span><span class="p">([</span>
    <span class="n">account</span><span class="p">,</span>
    <span class="n">BankAccount</span><span class="p">(</span><span class="n">balance</span><span class="o">=</span><span class="n">Amount</span><span class="p">(</span><span class="mi">10000</span><span class="p">,</span> <span class="s">&quot;cad&quot;</span><span class="p">)),</span>
    <span class="n">BankAccount</span><span class="p">(</span><span class="n">balance</span><span class="o">=</span><span class="n">Amount</span><span class="p">(</span><span class="mi">5700</span><span class="p">,</span> <span class="s">&quot;usd&quot;</span><span class="p">)),</span>
    <span class="n">BankAccount</span><span class="p">(</span><span class="n">balance</span><span class="o">=</span><span class="n">Amount</span><span class="p">(</span><span class="mi">89682</span><span class="p">,</span> <span class="s">&quot;aud&quot;</span><span class="p">)),</span>
<span class="p">])</span>
<span class="n">session</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
</pre></div>



<p>Above, all the balances are coerced from their source currencies to USD, via the <tt class="docutils literal">&#64;balance.setter</tt>
portion of our hybrid, which is using <tt class="docutils literal"><span class="pre">value.as_currency(&quot;usd&quot;)</span></tt>.</p>
<p>We can then query <tt class="docutils literal">BankAccount</tt> objects using the <tt class="docutils literal">.balance</tt> column more or less as is,
such as in a simple comparison:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">BankAccount</span><span class="p">)</span><span class="o">.</span>\
<span class="gp">... </span>   <span class="nb">filter</span><span class="p">(</span><span class="n">BankAccount</span><span class="o">.</span><span class="n">balance</span> <span class="o">==</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">10000</span><span class="p">,</span> <span class="s">&quot;cad&quot;</span><span class="p">))</span><span class="o">.</span><span class="n">one</span><span class="p">()</span>
<span class="go">SELECT bank_account.balance AS bank_account_balance, bank_account.id AS bank_account_id</span>
<span class="go">FROM bank_account</span>
<span class="go">WHERE bank_account.balance = ?</span>
<span class="go">(9886.11,)</span>
<span class="go">BankAccount(9886.1100 usd)</span>
</pre></div>



<p>Notice above the value was converted on the Python side before being converted to a
SQL expression.  This is due to the coercion occurring upon the right side, which
is an <tt class="docutils literal">Amount</tt> object against a numeric in-Python value.</p>
<p>If we told the left side to convert itself, then we'd be getting the currency
conversions on the SQL side as well:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">BankAccount</span><span class="p">)</span><span class="o">.</span>\
<span class="gp">... </span>   <span class="nb">filter</span><span class="p">(</span><span class="n">BankAccount</span><span class="o">.</span><span class="n">balance</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="s">&quot;cad&quot;</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">9999</span><span class="p">,</span> <span class="s">&quot;cad&quot;</span><span class="p">))</span><span class="o">.</span>\
<span class="gp">... </span>   <span class="nb">filter</span><span class="p">(</span><span class="n">BankAccount</span><span class="o">.</span><span class="n">balance</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="s">&quot;cad&quot;</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">Amount</span><span class="p">(</span><span class="mi">10001</span><span class="p">,</span> <span class="s">&quot;cad&quot;</span><span class="p">))</span><span class="o">.</span>\
<span class="gp">... </span>   <span class="n">one</span><span class="p">()</span>
<span class="go">SELECT bank_account.balance AS bank_account_balance, bank_account.id AS bank_account_id</span>
<span class="go">FROM bank_account</span>
<span class="go">WHERE ? * bank_account.balance &gt; ? AND ? * bank_account.balance &lt; ?</span>
<span class="go">(1.01152, 9999.0, 1.01152, 10001.0)</span>
<span class="go">BankAccount(9886.1100 usd)</span>
</pre></div>



<p>So far the above operations take advantage of the fact that the <tt class="docutils literal">__eq__()</tt>, <tt class="docutils literal">__lt__()</tt>
and <tt class="docutils literal">__gt__()</tt> methods of <tt class="docutils literal">Amount</tt> are returning SQL expressions.  To interpret
the <tt class="docutils literal">Amount</tt> object directly, at the moment we need to use the <tt class="docutils literal">.amount</tt> accessor:</p>


<div class="pygments_manni"><pre><span class="gp">&gt;&gt;&gt; </span><span class="c"># print all amounts as CAD</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">BankAccount</span><span class="o">.</span><span class="n">balance</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="s">&quot;cad&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">amount</span><span class="p">)</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
<span class="go">SELECT ? * bank_account.balance AS anon_1</span>
<span class="go">FROM bank_account</span>
<span class="go">(1.01152,)</span>
<span class="go">[(Decimal(&#39;4046.0800000000&#39;),), (Decimal(&#39;9999.9979872000&#39;),), (Decimal(&#39;5765.6640000000&#39;),), (Decimal(&#39;93402.1189872768&#39;),)]</span>

<span class="gp">&gt;&gt;&gt; </span><span class="c"># return the average balance in EUR</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">func</span><span class="o">.</span><span class="n">avg</span><span class="p">(</span><span class="n">BankAccount</span><span class="o">.</span><span class="n">balance</span><span class="o">.</span><span class="n">as_currency</span><span class="p">(</span><span class="s">&quot;eur&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">amount</span><span class="p">))</span><span class="o">.</span><span class="n">scalar</span><span class="p">()</span>
<span class="go">SELECT avg(? * bank_account.balance) AS avg_1</span>
<span class="go">FROM bank_account</span>
<span class="go">(0.724743,)</span>
<span class="go">20279.1228162</span>
</pre></div>



<p>The situation can be improved in most cases if we add a
<tt class="docutils literal">__clause_element__()</tt> method to our <tt class="docutils literal">Amount</tt> class - the full example
script includes this.  There's also a few other rough edges to this approach which I may try
to address in a future release.  But overall, I use this pattern quite a bit as presented in several
ways.  It in fact stretches all the way back to similar patterns I used when I was primarily a Java
programmer, though the Python version is much more flexible.  It allows you to forget about
certain kinds of numeric conversion details which now take care of themselves,
even in SQL expressions, in a simple and transparent way.</p>
</div>
<div class="section" id="downloads">
<h1>Downloads</h1>
<ul class="simple">
<li><a class="reference external" href="/files/2011/account.py">account.py</a> - basic hybrid example</li>
<li><a class="reference external" href="/files/2011/account_currency.py">account_currency.py</a> - value agnostic type example</li>
</ul>
</div>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://techspot.zzzeek.org</uri>
    </author>
    <title type="html"><![CDATA[SQLAlchemy - an Architectural Retrospective]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2011/09/25/sqlalchemy-an-architectural-retrospective" />
    <id>http://techspot.zzzeek.org/2011/09/25/sqlalchemy-an-architectural-retrospective</id>
    <updated>2011-09-25T16:01:00Z</updated>
    <published>2011-09-25T16:01:00Z</published>
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <summary type="html"><![CDATA[SQLAlchemy - an Architectural Retrospective]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2011/09/25/sqlalchemy-an-architectural-retrospective"><![CDATA[<div class="document">
<p>The video of my PyGotham talk, <a class="reference external" href="http://blip.tv/pygotham_2011/sqlalchemy-an-architectural-retrospective-5583765">SQLAlchemy, an Architectural Retrospective</a> is now available
at <a class="reference external" href="http://blip.tv/pygotham_2011/sqlalchemy-an-architectural-retrospective-5583765">blip.tv</a>.   This talk details my
current thinking on SQLAlchemy philosophy and then proceeds through architectural overviews of several key areas, including
the core operation of the Unit of Work.  The
accompanying slides are available in <a class="reference external" href="/files/2011/sqla_arch_retro.key.pdf">PDF form</a> as well. Enjoy !</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://techspot.zzzeek.org</uri>
    </author>
    <title type="html"><![CDATA[SQLAlchemy at PyGotham]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2011/09/16/sqlalchemy-at-pygotham" />
    <id>http://techspot.zzzeek.org/2011/09/16/sqlalchemy-at-pygotham</id>
    <updated>2011-09-16T16:01:00Z</updated>
    <published>2011-09-16T16:01:00Z</published>
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <summary type="html"><![CDATA[SQLAlchemy at PyGotham]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2011/09/16/sqlalchemy-at-pygotham"><![CDATA[<div class="document">
<p>Just finished my SQLAlchemy talk at <a class="reference external" href="http://pygotham.org/">PyGotham</a>.    In this talk, I get into
my latest thinking on SQLAlchemy's usage philosophy and cover a few architectural features
that I discuss in my upcoming chapter for <a class="reference external" href="http://www.aosabook.org/">Architecture of Open Source Applications</a>.
Here's the slides in PDF Form: <a class="reference external" href="/files/2011/sqla_arch_retro.key.pdf">SQLAlchemy - an Architectural Retrospective</a>.
There should eventually be a video at some point I'll keep you posted !</p>
<p><strong>Update</strong> - The video is now <a class="reference external" href="/2011/09/25/sqlalchemy-an-architectural-retrospective/">available</a>.</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://techspot.zzzeek.org</uri>
    </author>
    <title type="html"><![CDATA[ORM Thoughts (in < 140 x 5 characters)]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2011/06/16/orm-thoughts-in-140-x-5-characters" />
    <id>http://techspot.zzzeek.org/2011/06/16/orm-thoughts-in-140-x-5-characters</id>
    <updated>2011-06-16T19:29:00Z</updated>
    <published>2011-06-16T19:29:00Z</published>
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <summary type="html"><![CDATA[ORM Thoughts (in < 140 x 5 characters)]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2011/06/16/orm-thoughts-in-140-x-5-characters"><![CDATA[<div class="document">
<p>When I wrote SQLAlchemy, a key intent was as a working rebuttal to the &quot;ORM is vietnam&quot; argument.   (edit: for those who don't know where that phrase originates, it starts with this <a class="reference external" href="http://blogs.tedneward.com/2006/06/26/The+Vietnam+Of+Computer+Science.aspx">very famous post</a>.)</p>
<p>This was achieved by: a. tweaking the key assumption that relational concepts must be hidden.  They don't.  Practicality beats purity.</p>
<p>And b. not underestimating the task, i.e. unit of work, cached
collections and associations backed by eager loading (solving N+1 problem).</p>
<p>Hibernate does both, but suffers from the limitations of Java - complex, heavyhanded.  Python is what makes SQLAlchemy possible.</p>
<p>Our users can now write super-SQL-fluent apps succinctly and quickly; that's all the proof one should need that ORM is definitely worth it.</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://techspot.zzzeek.org</uri>
    </author>
    <title type="html"><![CDATA[Magic, a "New" ORM]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2011/05/17/magic-a-new-orm" />
    <id>http://techspot.zzzeek.org/2011/05/17/magic-a-new-orm</id>
    <updated>2011-05-17T23:36:00Z</updated>
    <published>2011-05-17T23:36:00Z</published>
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <summary type="html"><![CDATA[Magic, a "New" ORM]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2011/05/17/magic-a-new-orm"><![CDATA[<div class="document">
<p><strong>TL;DR</strong> - Use SQLAlchemy to create <em>your own</em> Magic.</p>
<p>It's new, and easy!  That's why we call it what it is:  <strong>Magic</strong>.
A new ORM that keeps things simple.  Let's dive in !</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">magic</span> <span class="kn">import</span> <span class="p">(</span>
            <span class="n">Entity</span><span class="p">,</span> <span class="n">one_to_many</span><span class="p">,</span> <span class="n">many_to_one</span><span class="p">,</span> <span class="n">many_to_many</span><span class="p">,</span> <span class="n">string</span>
        <span class="p">)</span>
</pre></div>



<p><strong>I like this so far !   What does a new model class look like ?</strong></p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">Parent</span><span class="p">(</span><span class="n">Entity</span><span class="p">):</span>
    <span class="n">children</span> <span class="o">=</span> <span class="n">one_to_many</span><span class="p">(</span><span class="s">&quot;Child&quot;</span><span class="p">,</span> <span class="s">&quot;child_id&quot;</span><span class="p">,</span>
                            <span class="n">reverse</span><span class="o">=</span><span class="s">&quot;parent&quot;</span><span class="p">)</span>
</pre></div>



<p><strong>No. Way.  That's it ?   No tables and columns ?  No foreign thingies ?
Where's the meaningless boilerplate ?</strong></p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">Child</span><span class="p">(</span><span class="n">Entity</span><span class="p">):</span>
    <span class="n">parent</span> <span class="o">=</span> <span class="n">many_to_one</span><span class="p">(</span><span class="s">&quot;Parent&quot;</span><span class="p">,</span> <span class="s">&quot;child_id&quot;</span><span class="p">,</span>
                            <span class="n">reverse</span><span class="o">=</span><span class="s">&quot;children&quot;</span><span class="p">)</span>

    <span class="n">tags</span> <span class="o">=</span> <span class="n">many_to_many</span><span class="p">(</span><span class="s">&quot;Tag&quot;</span><span class="p">,</span> <span class="s">&quot;child_tag&quot;</span><span class="p">,</span>
                                <span class="s">&quot;child_id&quot;</span><span class="p">,</span>
                                <span class="s">&quot;tag_id&quot;</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Tag</span><span class="p">(</span><span class="n">Entity</span><span class="p">):</span>
    <span class="n">name</span> <span class="o">=</span> <span class="n">string</span><span class="p">(</span><span class="mi">50</span><span class="p">)</span>
</pre></div>



<p><strong>OK that's a little more chatty but seriously zzzeek, don't you want some
weird &quot;==&quot; signs in there ?</strong></p>


<div class="pygments_manni"><pre><span class="n">Entity</span><span class="o">.</span><span class="n">setup_database</span><span class="p">(</span><span class="s">&quot;sqlite://&quot;</span><span class="p">,</span> <span class="n">create</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
</pre></div>



<p><strong>This is beginning to remind me of washing machines that also have a dryer built inside of them,
or those TVs that have VCRs embedded inside the case.</strong></p>


<div class="pygments_manni"><pre><span class="n">t1</span><span class="p">,</span> <span class="n">t2</span><span class="p">,</span> <span class="n">t3</span> <span class="o">=</span> <span class="n">Tag</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">&#39;t1&#39;</span><span class="p">),</span> <span class="n">Tag</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">&#39;t2&#39;</span><span class="p">),</span> <span class="n">Tag</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">&#39;t3&#39;</span><span class="p">)</span>
<span class="n">Entity</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">Parent</span><span class="p">(</span>
        <span class="n">children</span><span class="o">=</span><span class="p">{</span>
            <span class="n">Child</span><span class="p">(</span><span class="n">tags</span><span class="o">=</span><span class="p">{</span><span class="n">t1</span><span class="p">,</span> <span class="n">t2</span><span class="p">}),</span>
            <span class="n">Child</span><span class="p">(</span><span class="n">tags</span><span class="o">=</span><span class="p">{</span><span class="n">t1</span><span class="p">,</span> <span class="n">t3</span><span class="p">}),</span>
            <span class="n">Child</span><span class="p">()</span>
        <span class="p">}))</span>
<span class="n">Entity</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>

<span class="n">p1</span> <span class="o">=</span> <span class="n">Entity</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Parent</span><span class="p">)</span><span class="o">.</span><span class="n">first</span><span class="p">()</span>
<span class="k">for</span> <span class="n">child</span> <span class="ow">in</span> <span class="n">p1</span><span class="o">.</span><span class="n">children</span><span class="p">:</span>
    <span class="k">print</span> <span class="n">child</span><span class="p">,</span> <span class="p">[</span><span class="n">t</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">child</span><span class="o">.</span><span class="n">tags</span><span class="p">]</span>
</pre></div>



<p><strong>New-style sets!  Hooray for Python.</strong></p>
<p>And...that's it.   <strong>Magic!</strong></p>
<p>Would you want this ORM ?   Or would you want a different one ?   Well how does
Magic work ?   I'm pretty sure you can guess how it starts:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="p">(</span>
            <span class="n">Column</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">,</span> <span class="n">Table</span><span class="p">,</span>
            <span class="n">Integer</span><span class="p">,</span> <span class="n">String</span><span class="p">,</span> <span class="n">create_engine</span>
        <span class="p">)</span>
</pre></div>



<p><strong>There's the zzzeek we know !   Blah blah blah tables, constraints, boring things.
Well we might as well get on with it</strong>:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="p">(</span>
            <span class="n">class_mapper</span><span class="p">,</span> <span class="n">mapper</span><span class="p">,</span> <span class="n">relationship</span><span class="p">,</span>
            <span class="n">scoped_session</span><span class="p">,</span> <span class="n">sessionmaker</span><span class="p">,</span> <span class="n">configure_mappers</span>
        <span class="p">)</span>
<span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span> <span class="n">declared_attr</span><span class="p">,</span> <span class="n">declarative_base</span>
<span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">event</span>
<span class="kn">import</span> <span class="nn">re</span>
</pre></div>



<p><strong>I like how &quot;re&quot; is the honored guest of all that SQLAlchemy stuff.</strong></p>


<div class="pygments_manni"><pre><span class="nd">@event.listens_for</span><span class="p">(</span><span class="n">mapper</span><span class="p">,</span> <span class="s">&quot;mapper_configured&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_setup_deferred_properties</span><span class="p">(</span><span class="n">mapper</span><span class="p">,</span> <span class="n">class_</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Listen for finished mappers and apply DeferredProp</span>
<span class="sd">    configurations.&quot;&quot;&quot;</span>

    <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">class_</span><span class="o">.</span><span class="n">__dict__</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
        <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="n">DeferredProp</span><span class="p">):</span>
            <span class="n">value</span><span class="o">.</span><span class="n">_config</span><span class="p">(</span><span class="n">class_</span><span class="p">,</span> <span class="n">mapper</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span>
</pre></div>



<p><strong>And here we have our first docstring.   What is this &quot;event&quot; you speak of ?</strong></p>
<p><strong>zzzeek says:</strong> That's the new thing in 0.7 !   You're going to get a lot
of mileage out of it - everything that used to be extension this, listener
that, all goes through <tt class="docutils literal">event</tt>.  And there's lots of new events added
with more on the way.</p>
<p>For this one in particular, just like it says, anytime a new mapper
appears, this thing is going to run and....work all the <em>magic</em>.</p>
<p><strong>Well it was nice while it lasted, I guess it's about to get ugly huh.</strong></p>
<p>Deep breath,  just a slight pinch:</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">DeferredProp</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;A class attribute that generates a mapped attribute</span>
<span class="sd">    after mappers are configured.&quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">_setup_reverse</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">rel</span><span class="p">,</span> <span class="n">target_cls</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Setup bidirectional behavior between two relationships.&quot;&quot;&quot;</span>

        <span class="n">reverse</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">kw</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&#39;reverse&#39;</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">reverse</span><span class="p">:</span>
            <span class="n">reverse_attr</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">target_cls</span><span class="p">,</span> <span class="n">reverse</span><span class="p">)</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">reverse_attr</span><span class="p">,</span> <span class="n">DeferredProp</span><span class="p">):</span>
                <span class="n">reverse_attr</span><span class="o">.</span><span class="n">property</span><span class="o">.</span><span class="n">_add_reverse_property</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
                <span class="n">rel</span><span class="o">.</span><span class="n">_add_reverse_property</span><span class="p">(</span><span class="n">reverse</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">FKRelationship</span><span class="p">(</span><span class="n">DeferredProp</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Generates a one to many or many to one relationship.&quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="n">fk_col</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">fk_col</span> <span class="o">=</span> <span class="n">fk_col</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">kw</span> <span class="o">=</span> <span class="n">kw</span>

    <span class="k">def</span> <span class="nf">_config</span><span class="p">(</span><span class="bp">self</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="sd">&quot;&quot;&quot;Create a Column with ForeignKey as well as a relationship().&quot;&quot;&quot;</span>

        <span class="n">target_cls</span> <span class="o">=</span> <span class="n">cls</span><span class="o">.</span><span class="n">_decl_class_registry</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">]</span>

        <span class="n">pk_target</span><span class="p">,</span> <span class="n">fk_target</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_pk_fk</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">target_cls</span><span class="p">)</span>
        <span class="n">pk_table</span> <span class="o">=</span> <span class="n">pk_target</span><span class="o">.</span><span class="n">__table__</span>
        <span class="n">pk_col</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">pk_table</span><span class="o">.</span><span class="n">primary_key</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>

        <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">fk_target</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">fk_col</span><span class="p">):</span>
            <span class="n">fk_col</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">fk_target</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">fk_col</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">fk_col</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fk_col</span><span class="p">,</span> <span class="n">pk_col</span><span class="o">.</span><span class="n">type</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="n">pk_col</span><span class="p">))</span>
            <span class="nb">setattr</span><span class="p">(</span><span class="n">fk_target</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">fk_col</span><span class="p">,</span> <span class="n">fk_col</span><span class="p">)</span>

        <span class="n">rel</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="n">target_cls</span><span class="p">,</span>
                <span class="n">primaryjoin</span><span class="o">=</span><span class="n">fk_col</span><span class="o">==</span><span class="n">pk_col</span><span class="p">,</span>
                <span class="n">collection_class</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">kw</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&#39;collection_class&#39;</span><span class="p">,</span> <span class="nb">set</span><span class="p">)</span>
            <span class="p">)</span>
        <span class="nb">setattr</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">rel</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_setup_reverse</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">rel</span><span class="p">,</span> <span class="n">target_cls</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">one_to_many</span><span class="p">(</span><span class="n">FKRelationship</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Generates a one to many relationship.&quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">_get_pk_fk</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cls</span><span class="p">,</span> <span class="n">target_cls</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">cls</span><span class="p">,</span> <span class="n">target_cls</span>

<span class="k">class</span> <span class="nc">many_to_one</span><span class="p">(</span><span class="n">FKRelationship</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Generates a many to one relationship.&quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">_get_pk_fk</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cls</span><span class="p">,</span> <span class="n">target_cls</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">target_cls</span><span class="p">,</span> <span class="n">cls</span>

<span class="k">class</span> <span class="nc">many_to_many</span><span class="p">(</span><span class="n">DeferredProp</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Generates a many to many relationship.&quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="n">tablename</span><span class="p">,</span> <span class="n">local</span><span class="p">,</span> <span class="n">remote</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">tablename</span> <span class="o">=</span> <span class="n">tablename</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">local</span> <span class="o">=</span> <span class="n">local</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">remote</span> <span class="o">=</span> <span class="n">remote</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">kw</span> <span class="o">=</span> <span class="n">kw</span>

    <span class="k">def</span> <span class="nf">_config</span><span class="p">(</span><span class="bp">self</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="sd">&quot;&quot;&quot;Create an association table between parent/target</span>
<span class="sd">        as well as a relationship().&quot;&quot;&quot;</span>

        <span class="n">target_cls</span> <span class="o">=</span> <span class="n">cls</span><span class="o">.</span><span class="n">_decl_class_registry</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">target</span><span class="p">]</span>
        <span class="n">local_pk</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">cls</span><span class="o">.</span><span class="n">__table__</span><span class="o">.</span><span class="n">primary_key</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
        <span class="n">target_pk</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">target_cls</span><span class="o">.</span><span class="n">__table__</span><span class="o">.</span><span class="n">primary_key</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>

        <span class="n">t</span> <span class="o">=</span> <span class="n">Table</span><span class="p">(</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">tablename</span><span class="p">,</span>
                <span class="n">cls</span><span class="o">.</span><span class="n">metadata</span><span class="p">,</span>
                <span class="n">Column</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">local</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="n">local_pk</span><span class="p">),</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">),</span>
                <span class="n">Column</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">remote</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="n">target_pk</span><span class="p">),</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">),</span>
                <span class="n">keep_existing</span><span class="o">=</span><span class="bp">True</span>
            <span class="p">)</span>
        <span class="n">rel</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="n">target_cls</span><span class="p">,</span>
                <span class="n">secondary</span><span class="o">=</span><span class="n">t</span><span class="p">,</span>
                <span class="n">collection_class</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">kw</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&#39;collection_class&#39;</span><span class="p">,</span> <span class="nb">set</span><span class="p">)</span>
            <span class="p">)</span>
        <span class="nb">setattr</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">rel</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_setup_reverse</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">rel</span><span class="p">,</span> <span class="n">target_cls</span><span class="p">)</span>
</pre></div>



<p><strong>That was highly unpleasant.   Please don't paste that much code again.</strong></p>
<p><strong>zzzeek says:</strong>  OK!   It's just doing the foreign key and relationship() for us.
If you've worked with straight SQLAlchemy before, most of what's in there
shouldn't be too mysterious.</p>
<p>We're getting
the &quot;target&quot; of the relationship using <tt class="docutils literal">_decl_class_registry</tt>, a dictionary that
gives us the target class based on the string, which is put
there by Declarative.  We're looking at the existing classes and their
<tt class="docutils literal">__table__</tt> to get at the appropriate primary key (assumed to be non-composite....
a little more <em>magic</em> could certainly improve upon that though!),
we create a <tt class="docutils literal">Column()</tt> with
<tt class="docutils literal">ForeignKey()</tt> the way you'd normally be doing for all your mapped classes
individually, or in the case of many-to-many we just put two of them
into a <tt class="docutils literal">Table</tt>.  Then we send out a <tt class="docutils literal">relationship()</tt> with what we've come up with.  We can
stick these attributes right on the classes and Declarative takes care of
making sure they are mapped and such.</p>
<p>It's an entirely alternate form of <tt class="docutils literal">relationship</tt> in just 80 lines - there's
lots of ways to play with things like this. I personally don't need this much
re-working of SQLAlchemy's usual <tt class="docutils literal">relationship()</tt> syntax, and I think most of our
users don't either - but the job first and foremost of <tt class="docutils literal">relationship()</tt>
is to have awesome functionality.  I've seen some requests sometimes to
make it do things like this, and one of our goals is to make whatever customizations
people need as doable as possible.   Patterns like these can change how the
rest of your project looks.    That one is pretty ambitious - but there's plenty
of others that are a lot simpler, and can really cut down on noise throughout
the bulk of mapping code:</p>


<div class="pygments_manni"><pre><span class="k">def</span> <span class="nf">string</span><span class="p">(</span><span class="n">size</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Convenience macro, return a Column with String.&quot;&quot;&quot;</span>

    <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="n">size</span><span class="p">))</span>

<span class="k">def</span> <span class="nf">int</span><span class="p">():</span>
    <span class="sd">&quot;&quot;&quot;Convenience macro, return a Column with Integer.&quot;&quot;&quot;</span>

    <span class="k">return</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">)</span>
</pre></div>



<p><strong>Why thank you !</strong></p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">Base</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Base class which auto-generates tablename, surrogate</span>
<span class="sd">    primary key column.</span>

<span class="sd">    Also includes a scoped session and a database generator.</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="nd">@declared_attr</span>
    <span class="k">def</span> <span class="nf">__tablename__</span><span class="p">(</span><span class="n">cls</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Convert CamelCase class name to underscores_between_words</span>
<span class="sd">        table name.&quot;&quot;&quot;</span>
        <span class="n">name</span> <span class="o">=</span> <span class="n">cls</span><span class="o">.</span><span class="n">__name__</span>
        <span class="k">return</span> <span class="p">(</span>
            <span class="n">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">+</span>
            <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s">r&#39;([A-Z])&#39;</span><span class="p">,</span> <span class="k">lambda</span> <span class="n">m</span><span class="p">:</span><span class="s">&quot;_&quot;</span> <span class="o">+</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="n">name</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
        <span class="p">)</span>

    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="sd">&quot;&quot;&quot;Surrogate &#39;id&#39; primary key column.&quot;&quot;&quot;</span>

    <span class="nd">@classmethod</span>
    <span class="k">def</span> <span class="nf">setup_database</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">create</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">echo</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;&#39;Setup everything&#39; method for the ultra lazy.&quot;&quot;&quot;</span>

        <span class="n">configure_mappers</span><span class="p">()</span>
        <span class="n">e</span> <span class="o">=</span> <span class="n">create_engine</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">echo</span><span class="o">=</span><span class="n">echo</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">create</span><span class="p">:</span>
            <span class="n">cls</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">create_all</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
        <span class="n">cls</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">scoped_session</span><span class="p">(</span><span class="n">sessionmaker</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>

<span class="n">Entity</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">(</span><span class="n">cls</span><span class="o">=</span><span class="n">Base</span><span class="p">)</span>
</pre></div>



<p><strong>Well now !   Why didn't you tell us you could do that before ?   I've been putting
__tablename__ and columns all over the place.</strong></p>
<p><strong>zzzeek says:</strong>  We get into it to a good degree when we talk about &quot;mixins&quot;
<a class="reference external" href="http://www.sqlalchemy.org/docs/07/orm/extensions/declarative.html#mixin-classes">here</a> , most of
what mixins do can go on your &quot;base&quot; as well.</p>
<p><strong>Alrighty.  Short blog post today?</strong></p>
<p><strong>zzzeek says:</strong> Indeed.   The moral of the story is, SQLAlchemy isn't a framework, and never
was...it's a <em>toolkit</em> - you should build things !</p>
<p>Look for SQLAlchemy 0.7's production release soon, in the meantime here's
some <a class="reference external" href="/files/2011/magic.py">magic</a>.</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://techspot.zzzeek.org</uri>
    </author>
    <title type="html"><![CDATA[The Enum Recipe]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2011/01/14/the-enum-recipe" />
    <id>http://techspot.zzzeek.org/2011/01/14/the-enum-recipe</id>
    <updated>2011-01-14T17:46:00Z</updated>
    <published>2011-01-14T17:46:00Z</published>
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <summary type="html"><![CDATA[The Enum Recipe]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2011/01/14/the-enum-recipe"><![CDATA[<div class="document">
<p>In the most general sense an <em>enumeration</em> is an exact listing of all the
elements of a set. In software design, enums are typically sets of fixed
string values that define some kind of discriminating value within an
application. In contrast to a generic &quot;dropdown&quot; list, such as a selection of
timezones, country names, or years in a date picker, the enum usually refers
to values that are also explicit within the application's source code, such as
&quot;debit&quot; or &quot;credit&quot; in an accounting application, &quot;draft&quot; or &quot;publish&quot; in a
CMS, &quot;everyone&quot;, &quot;friends of friends&quot;, or &quot;friends only&quot; in your typical
social media sell-your-details-to-the-highest-bidder system. Differing values
have a direct impact on business logic. Adding new values to the list usually
corresponds with the addition of some new logic in the application to
accommodate its meaning.</p>
<p>The requirements for an application-level enumeration are usually:</p>
<ol class="arabic simple">
<li>Can represent a single value within application logic with no chance of specifying
a non-existent value (i.e., we don't want to hardcode strings or numbers).</li>
<li>Can associate each value with a textual description suitable for a user interface.</li>
<li>Can get the list of all possible values, usually for user interface display.</li>
<li>Can efficiently associate the discriminatory value with many database records.</li>
</ol>
<p>Representing an enumerated value in a relational database often goes like this:</p>


<div class="pygments_manni"><pre><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">employee_type</span> <span class="p">(</span>
    <span class="n">id</span> <span class="nb">INTEGER</span> <span class="k">PRIMARY</span> <span class="k">KEY</span><span class="p">,</span>
    <span class="n">description</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">30</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span>
<span class="p">);</span>

<span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">employee</span> <span class="p">(</span>
    <span class="n">id</span> <span class="nb">INTEGER</span> <span class="k">PRIMARY</span> <span class="k">KEY</span><span class="p">,</span>
    <span class="n">name</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">60</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
    <span class="k">type</span> <span class="nb">INTEGER</span> <span class="k">REFERENCES</span> <span class="n">employee_type</span><span class="p">(</span><span class="n">id</span><span class="p">)</span>
<span class="p">);</span>

<span class="k">INSERT</span> <span class="k">INTO</span> <span class="n">employee_type</span> <span class="p">(</span><span class="n">id</span><span class="p">,</span> <span class="n">description</span><span class="p">)</span> <span class="k">VALUES</span>
    <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;Part Time&#39;</span><span class="p">),</span>
    <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="s1">&#39;Full Time&#39;</span><span class="p">),</span>
    <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="s1">&#39;Contractor&#39;</span><span class="p">);</span>
</pre></div>



<p>Above we use the example of a database of employees and their status.  Advantages
of the above include:</p>
<ol class="arabic simple">
<li>The choice of &quot;employee type&quot; is constrained.</li>
<li>The textual descriptions of employees are associated with the constrained value.</li>
<li>New employee types can be added just by adding a new row.</li>
<li>Queries can be written directly against the data that produce textual displays
of discriminator values, without leaving the database console.</li>
</ol>
<p>But as we all know this approach also has disadvantages:</p>
<ol class="arabic simple">
<li>It's difficult to avoid hardcoding integer IDs in our application.  Adding a character
based &quot;code&quot; field to the <tt class="docutils literal">employee_type</tt> table, even making the character
field the primary key, can ameliorate this, but this is not information that would
otherwise be needed in the database.  Our DBAs also got grumpy when we proposed
a character-based primary key.</li>
<li>To display choices in dropdowns, as well as to display the textual description of
the value associated with a particular piece of data, we need to query the
database for the text - either by loading them into an in-memory lookup
ahead of time, or by joining to the lookup table when we query the base
table. This adds noise and boilerplate to the application.</li>
<li>For each new data-driven enumerative type used by the application, we need to add
a new table, and populate.</li>
<li>When the descriptive names change, we have to update the database, tying database
migration work to what would normally be a user-interface-only update.</li>
<li>Whatever framework we build around these lookup tables, doesn't really work
for enumerations that don't otherwise need to be persisted.</li>
<li>If we moved to a non-relational database, we'd probably do this completely
differently.</li>
</ol>
<p>Basically, this approach is tedious and puts information about the enum further
away from the application code than we'd prefer.</p>
<p>An alternative to the lookup table is to use a database supplied enumeration.  Both MySQL
and Postgresql (as of 8.3) offer an ENUM type for this purpose.   It's
fairly straightforward to create an approximation of an ENUM datatype in most databases by using
a CHAR column in conjunction with a CHECK constraint, that tests incoming rows to be
within one of a set of possible values.</p>
<p>SQLAlchemy provides an <tt class="docutils literal">Enum</tt> type which abstracts this technique:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span> <span class="n">declarative_base</span>
<span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">Column</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">String</span><span class="p">,</span> <span class="n">Enum</span>
<span class="n">Base</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">Employee</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;employee&#39;</span>

    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">name</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="mi">60</span><span class="p">),</span> <span class="n">nullable</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
    <span class="nb">type</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Enum</span><span class="p">(</span><span class="s">&#39;part_time&#39;</span><span class="p">,</span> <span class="s">&#39;full_time&#39;</span><span class="p">,</span> <span class="s">&#39;contractor&#39;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">&#39;employee_types&#39;</span><span class="p">))</span>
</pre></div>



<p>On backends that support ENUM, a <tt class="docutils literal">metadata.create_all()</tt>
emits the appropriate DDL to generate the type.  The 'name' field of the <tt class="docutils literal">Enum</tt> is used as the
name of the type created in PG:</p>


<div class="pygments_manni"><pre><span class="k">CREATE</span> <span class="k">TYPE</span> <span class="n">employee_types</span> <span class="k">AS</span> <span class="n">ENUM</span> <span class="p">(</span><span class="s1">&#39;part_time&#39;</span><span class="p">,</span><span class="s1">&#39;full_time&#39;</span><span class="p">,</span><span class="s1">&#39;contractor&#39;</span><span class="p">)</span>

<span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">employee</span> <span class="p">(</span>
    <span class="n">id</span> <span class="nb">SERIAL</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
    <span class="n">name</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">60</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
    <span class="k">type</span> <span class="n">employee_types</span><span class="p">,</span>
    <span class="k">PRIMARY</span> <span class="k">KEY</span> <span class="p">(</span><span class="n">id</span><span class="p">)</span>
<span class="p">)</span>
</pre></div>



<p>On those that don't, it emits a <a href="#id1"><span class="problematic" id="id2">:strikeout:`CHAR`</span></a> VARCHAR datatype and additionally
emits DDL to generate an appropriate CHECK constraint.  Here, the 'name' field
is used as the name of the constraint:</p>
<div class="system-message" id="id1">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">&lt;string&gt;</tt>, line 109); <em><a href="#id2">backlink</a></em></p>
Unknown interpreted text role &quot;strikeout&quot;.</div>


<div class="pygments_manni"><pre><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">employee</span> <span class="p">(</span>
    <span class="n">id</span> <span class="nb">INTEGER</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
    <span class="n">name</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">60</span><span class="p">)</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span>
    <span class="k">type</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">10</span><span class="p">),</span>
    <span class="k">PRIMARY</span> <span class="k">KEY</span> <span class="p">(</span><span class="n">id</span><span class="p">),</span>
    <span class="k">CONSTRAINT</span> <span class="n">employee_types</span> <span class="k">CHECK</span> <span class="p">(</span><span class="k">type</span> <span class="k">IN</span> <span class="p">(</span><span class="s1">&#39;part_time&#39;</span><span class="p">,</span> <span class="s1">&#39;full_time&#39;</span><span class="p">,</span> <span class="s1">&#39;contractor&#39;</span><span class="p">))</span>
<span class="p">)</span>
</pre></div>



<p>In the case of PG's native ENUM, we're using the same space as a regular
integer (four bytes on PG).  In the case of CHAR/VARCHAR, keeping the size of
the symbols down to one or two characters should keep the size under four bytes
(database-specific overhead and encoding concerns may vary results).</p>
<p>To combine the ENUM database type with the other requirements of source-code level identification
and descriptive naming, we'll encapsulate the whole thing into a base class
that can be used to generate all kinds of enums:</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">EnumSymbol</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Define a fixed symbol tied to a parent class.&quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cls_</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">description</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">cls_</span> <span class="o">=</span> <span class="n">cls_</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">description</span> <span class="o">=</span> <span class="n">description</span>

    <span class="k">def</span> <span class="nf">__reduce__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Allow unpickling to return the symbol</span>
<span class="sd">        linked to the DeclEnum class.&quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="nb">getattr</span><span class="p">,</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cls_</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="nb">iter</span><span class="p">([</span><span class="bp">self</span><span class="o">.</span><span class="n">value</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">description</span><span class="p">])</span>

    <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;&lt;</span><span class="si">%s</span><span class="s">&gt;&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>

<span class="k">class</span> <span class="nc">EnumMeta</span><span class="p">(</span><span class="nb">type</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Generate new DeclEnum classes.&quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">classname</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">dict_</span><span class="p">):</span>
        <span class="n">cls</span><span class="o">.</span><span class="n">_reg</span> <span class="o">=</span> <span class="n">reg</span> <span class="o">=</span> <span class="n">cls</span><span class="o">.</span><span class="n">_reg</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
        <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">dict_</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
            <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
                <span class="n">sym</span> <span class="o">=</span> <span class="n">reg</span><span class="p">[</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> <span class="o">=</span> <span class="n">EnumSymbol</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="o">*</span><span class="n">v</span><span class="p">)</span>
                <span class="nb">setattr</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">sym</span><span class="p">)</span>
        <span class="k">return</span> <span class="nb">type</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">classname</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">dict_</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__iter__</span><span class="p">(</span><span class="n">cls</span><span class="p">):</span>
        <span class="k">return</span> <span class="nb">iter</span><span class="p">(</span><span class="n">cls</span><span class="o">.</span><span class="n">_reg</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>

<span class="k">class</span> <span class="nc">DeclEnum</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Declarative enumeration.&quot;&quot;&quot;</span>

    <span class="n">__metaclass__</span> <span class="o">=</span> <span class="n">EnumMeta</span>
    <span class="n">_reg</span> <span class="o">=</span> <span class="p">{}</span>

    <span class="nd">@classmethod</span>
    <span class="k">def</span> <span class="nf">from_string</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">cls</span><span class="o">.</span><span class="n">_reg</span><span class="p">[</span><span class="n">value</span><span class="p">]</span>
        <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                    <span class="s">&quot;Invalid value for </span><span class="si">%r</span><span class="s">: </span><span class="si">%r</span><span class="s">&quot;</span> <span class="o">%</span>
                    <span class="p">(</span><span class="n">cls</span><span class="o">.</span><span class="n">__name__</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
                <span class="p">)</span>

    <span class="nd">@classmethod</span>
    <span class="k">def</span> <span class="nf">values</span><span class="p">(</span><span class="n">cls</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">cls</span><span class="o">.</span><span class="n">_reg</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
</pre></div>



<p>Where above, <tt class="docutils literal">DeclEnum</tt> is the public interface.  There's a bit of fancy pants
stuff in there, but here's what it looks like in usage.
We build an <tt class="docutils literal">EmployeeType</tt> class, as a subclass of <tt class="docutils literal">DeclEnum</tt>, that has all the
things we want at once, with zero of anything else:</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">EmployeeType</span><span class="p">(</span><span class="n">DeclEnum</span><span class="p">):</span>
    <span class="n">part_time</span> <span class="o">=</span> <span class="s">&quot;part_time&quot;</span><span class="p">,</span> <span class="s">&quot;Part Time&quot;</span>
    <span class="n">full_time</span> <span class="o">=</span> <span class="s">&quot;full_time&quot;</span><span class="p">,</span> <span class="s">&quot;Full Time&quot;</span>
    <span class="n">contractor</span> <span class="o">=</span> <span class="s">&quot;contractor&quot;</span><span class="p">,</span> <span class="s">&quot;Contractor&quot;</span>
</pre></div>



<p>If we're trying to save space on a non-ENUM platform, we might use single
character values:</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">EmployeeType</span><span class="p">(</span><span class="n">DeclEnum</span><span class="p">):</span>
    <span class="n">part_time</span> <span class="o">=</span> <span class="s">&quot;P&quot;</span><span class="p">,</span> <span class="s">&quot;Part Time&quot;</span>
    <span class="n">full_time</span> <span class="o">=</span> <span class="s">&quot;F&quot;</span><span class="p">,</span> <span class="s">&quot;Full Time&quot;</span>
    <span class="n">contractor</span> <span class="o">=</span> <span class="s">&quot;C&quot;</span><span class="p">,</span> <span class="s">&quot;Contractor&quot;</span>
</pre></div>



<p>Our application references individual values using the class level symbols:</p>


<div class="pygments_manni"><pre><span class="n">employee</span> <span class="o">=</span> <span class="n">Employee</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">EmployeeType</span><span class="o">.</span><span class="n">part_time</span><span class="p">)</span>
<span class="c"># ...</span>
<span class="k">if</span> <span class="n">employee</span><span class="o">.</span><span class="n">type</span> <span class="ow">is</span> <span class="n">EmployeeType</span><span class="o">.</span><span class="n">part_time</span><span class="p">:</span>
    <span class="c"># do something with part time employee</span>
</pre></div>



<p>These symbols are global constants, hashable, and even pickleable,
thanks to the special <tt class="docutils literal">__reduce__</tt> above.</p>
<p>To get at value/description pairs for a dropdown, we can iterate the class as well
as the symbols themselves to get 2-tuples:</p>


<div class="pygments_manni"><pre><span class="o">&gt;&gt;&gt;</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">description</span> <span class="ow">in</span> <span class="n">EmployeeType</span><span class="p">:</span>
<span class="o">...</span>    <span class="k">print</span> <span class="n">key</span><span class="p">,</span> <span class="n">description</span>
<span class="n">P</span> <span class="n">Part</span> <span class="n">Time</span>
<span class="n">F</span> <span class="n">Full</span> <span class="n">Time</span>
<span class="n">C</span> <span class="n">Contractor</span>
</pre></div>



<p>To convert from a string value, as passed to us in a web request, to an <tt class="docutils literal">EmployeeType</tt> symbol,
we use <tt class="docutils literal">from_string()</tt>:</p>


<div class="pygments_manni"><pre><span class="nb">type</span> <span class="o">=</span> <span class="n">EmployeeType</span><span class="o">.</span><span class="n">from_string</span><span class="p">(</span><span class="s">&#39;P&#39;</span><span class="p">)</span>
</pre></div>



<p>The textual description is always available directly from the symbol itself:</p>


<div class="pygments_manni"><pre><span class="k">print</span> <span class="n">EmployeeType</span><span class="o">.</span><span class="n">contractor</span><span class="o">.</span><span class="n">description</span>
</pre></div>



<p>So we have application level constants, textual descriptions, and iteration.
The last step is persistence.   We'll use SQLAlchemy's <tt class="docutils literal">TypeDecorator</tt> to
augment the <tt class="docutils literal">Enum()</tt> type such that it can read and write our custom values:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">sqlalchemy.types</span> <span class="kn">import</span> <span class="n">SchemaType</span><span class="p">,</span> <span class="n">TypeDecorator</span><span class="p">,</span> <span class="n">Enum</span>
<span class="kn">import</span> <span class="nn">re</span>

<span class="k">class</span> <span class="nc">DeclEnumType</span><span class="p">(</span><span class="n">SchemaType</span><span class="p">,</span> <span class="n">TypeDecorator</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">enum</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">enum</span> <span class="o">=</span> <span class="n">enum</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">impl</span> <span class="o">=</span> <span class="n">Enum</span><span class="p">(</span>
                        <span class="o">*</span><span class="n">enum</span><span class="o">.</span><span class="n">values</span><span class="p">(),</span>
                        <span class="n">name</span><span class="o">=</span><span class="s">&quot;ck</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span>
                                    <span class="s">&#39;([A-Z])&#39;</span><span class="p">,</span>
                                    <span class="k">lambda</span> <span class="n">m</span><span class="p">:</span><span class="s">&quot;_&quot;</span> <span class="o">+</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span>
                                    <span class="n">enum</span><span class="o">.</span><span class="n">__name__</span><span class="p">)</span>
                    <span class="p">)</span>

    <span class="k">def</span> <span class="nf">_set_table</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">table</span><span class="p">,</span> <span class="n">column</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">impl</span><span class="o">.</span><span class="n">_set_table</span><span class="p">(</span><span class="n">table</span><span class="p">,</span> <span class="n">column</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">copy</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">DeclEnumType</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">enum</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">process_bind_param</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">dialect</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">None</span>
        <span class="k">return</span> <span class="n">value</span><span class="o">.</span><span class="n">value</span>

    <span class="k">def</span> <span class="nf">process_result_value</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">dialect</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">None</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">enum</span><span class="o">.</span><span class="n">from_string</span><span class="p">(</span><span class="n">value</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
</pre></div>



<p>The idea of <tt class="docutils literal">TypeDecorator</tt>, for those who haven't worked with it, is to provide
a wrapper around a plain database type to provide additional marshaling behavior
above what we need just to get consistency from the DBAPI.   The <tt class="docutils literal">impl</tt> datamember
refers to the type being wrapped.  In this case, <tt class="docutils literal">DeclEnumType</tt> generates
a new <tt class="docutils literal">Enum</tt> object using information from a given <tt class="docutils literal">DeclEnum</tt> subclass.  The name
of the enum is derived from the name of our class, using the world's
shortest camel-case-to-underscore converter.</p>
<p>The addition of <tt class="docutils literal">SchemaType</tt> as well as the <tt class="docutils literal">_set_table()</tt> method
represent a little bit of inside knowledge about the <tt class="docutils literal">sqlalchemy.types</tt>
module. <tt class="docutils literal">TypeDecorator</tt> currently does not automatically figure out from its
<tt class="docutils literal">impl</tt> that it needs to export additional functionality related to the
generation of the CHECK constraint and/or the CREATE TYPE. SQLAlchemy will try
to improve upon this at some point.</p>
<p>We can nicely wrap the creation of <tt class="docutils literal">DeclEnumType</tt> into our <tt class="docutils literal">DeclEnum</tt> via a new class
method:</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">DeclEnum</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Declarative enumeration.&quot;&quot;&quot;</span>

    <span class="c"># ...</span>

    <span class="nd">@classmethod</span>
    <span class="k">def</span> <span class="nf">db_type</span><span class="p">(</span><span class="n">cls</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">DeclEnumType</span><span class="p">(</span><span class="n">cls</span><span class="p">)</span>
</pre></div>



<p>So the full declaration and usage of our type looks like:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">Column</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">String</span>
<span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span> <span class="n">declarative_base</span>

<span class="k">class</span> <span class="nc">EmployeeType</span><span class="p">(</span><span class="n">DeclEnum</span><span class="p">):</span>
    <span class="n">part_time</span> <span class="o">=</span> <span class="s">&quot;P&quot;</span><span class="p">,</span> <span class="s">&quot;Part Time&quot;</span>
    <span class="n">full_time</span> <span class="o">=</span> <span class="s">&quot;F&quot;</span><span class="p">,</span> <span class="s">&quot;Full Time&quot;</span>
    <span class="n">contractor</span> <span class="o">=</span> <span class="s">&quot;C&quot;</span><span class="p">,</span> <span class="s">&quot;Contractor&quot;</span>

<span class="n">Base</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">Employee</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;employee&#39;</span>

    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">name</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="mi">60</span><span class="p">),</span> <span class="n">nullable</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
    <span class="nb">type</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">EmployeeType</span><span class="o">.</span><span class="n">db_type</span><span class="p">())</span>
</pre></div>



<p>Our <tt class="docutils literal">Employee</tt> class will persist its 'type' field into a new ENUM on the
database side, and on the Python side we use exclusively <tt class="docutils literal">EmployeeType.part_time</tt>,
<tt class="docutils literal">EmployeeType.full_time</tt>, <tt class="docutils literal">EmployeeType.contractor</tt> as values for the
'type' attribute.</p>
<p>The enum is also ideal for so-called polymorphic-discriminators, where different
values indicate the usage of different subclasses of <tt class="docutils literal">Employee</tt>:</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">Employee</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;employee&#39;</span>

    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
    <span class="n">name</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">(</span><span class="mi">60</span><span class="p">),</span> <span class="n">nullable</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
    <span class="nb">type</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">EmployeeType</span><span class="o">.</span><span class="n">db_type</span><span class="p">())</span>
    <span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;polymorphic_on&#39;</span><span class="p">:</span><span class="nb">type</span><span class="p">}</span>

<span class="k">class</span> <span class="nc">PartTimeEmployee</span><span class="p">(</span><span class="n">Employee</span><span class="p">):</span>
    <span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;polymorphic_identity&#39;</span><span class="p">:</span><span class="n">EmployeeType</span><span class="o">.</span><span class="n">part_time</span><span class="p">}</span>
</pre></div>



<p><tt class="docutils literal">TypeDecorator</tt> also takes care of coercing Python values used in expressions into the
appropriate SQLAlchemy type, so that the constants are usable in queries:</p>


<div class="pygments_manni"><pre><span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Employee</span><span class="p">)</span><span class="o">.</span><span class="n">filter_by</span><span class="p">(</span><span class="nb">type</span><span class="o">=</span><span class="n">EmployeeType</span><span class="o">.</span><span class="n">contractor</span><span class="p">)</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
</pre></div>



<p>A runnable demo of the enumeration recipe is packed up at <a class="reference external" href="/files/2011/decl_enum.py">decl_enum.py</a></p>
</div>
]]></content>
  </entry>
</feed>

