<?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>2013-05-17T04:32:10Z</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[Introduction to SQLAlchemy - Pycon 2013 - Wrapup]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2013/04/04/introduction-to-sqlalchemy-pycon-2013-wrapup" />
    <id>http://techspot.zzzeek.org/2013/04/04/introduction-to-sqlalchemy-pycon-2013-wrapup</id>
    <updated>2013-04-04T16:10:00Z</updated>
    <published>2013-04-04T16:10:00Z</published>
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <summary type="html"><![CDATA[Introduction to SQLAlchemy - Pycon 2013 - Wrapup]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2013/04/04/introduction-to-sqlalchemy-pycon-2013-wrapup"><![CDATA[<div class="document">
<p>Video is up for my Pycon 2013 tutorial <a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/16/">Introduction to SQLAlchemy</a>.</p>
<p>For those who want to follow along at home, the full code and prerequisite material is available here:</p>
<ul class="simple">
<li><a class="reference external" href="https://bitbucket.org/zzzeek/pycon2013_student_package">Prerequisite code</a></li>
<li><a class="reference external" href="https://speakerdeck.com/zzzeek/introduction-to-sqlalchemy-pycon-2013">Slides on Speakerdeck</a></li>
</ul>
<p><span class="raw-html"><iframe width="640" height="360" src="http://www.youtube.com/embed/woKYyhLCcnU?feature=player_detailpage" frameborder="0" allowfullscreen></iframe></span></p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://techspot.zzzeek.org</uri>
    </author>
    <title type="html"><![CDATA[Introduction to SQLAlchemy - Pycon 2013]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2013/03/05/introduction-to-sqlalchemy-pycon-2013" />
    <id>http://techspot.zzzeek.org/2013/03/05/introduction-to-sqlalchemy-pycon-2013</id>
    <updated>2013-03-05T17:10:00Z</updated>
    <published>2013-03-05T17:10:00Z</published>
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <summary type="html"><![CDATA[Introduction to SQLAlchemy - Pycon 2013]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2013/03/05/introduction-to-sqlalchemy-pycon-2013"><![CDATA[<div class="document">
<p>Preparations are just about complete for my upcoming tutorial
<a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/16/">Introduction to SQLAlchemy</a>.
There's a good crowd of people already attending, and I <em>think</em> registration is still open in case
more people want to sign up.</p>
<p>But in any case, if you are coming, this year there is <a class="reference external" href="https://us.pycon.org/2013/community/tutorials/16/">prerequisite material</a>, including the software installs as well as
a &quot;Relational Overview&quot; section that covers the basics of SQL and relational databases.
Everyone coming to the tutorial should read through this document, so that we're all
on roughly the same page regarding upfront SQL knowledge, and try to get the software
installed.   If there's any issues with the software, please report <a class="reference external" href="https://bitbucket.org/zzzeek/pycon2013_student_package/issues?status=new&amp;status=open">bugs</a> to me and we'll try to get
them resolved by tutorial time.   We will also be available at the <a class="reference external" href="https://us.pycon.org/2013/community/welcome/">Wednesday 6:30pm tutorial setup session</a> to help with installs.</p>
<p>Historically, tutorials pack the whole three hours of material up pretty solidly, and I hope I can balance getting lots of coverage versus not talking too fast.  Thanks for signing up !</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://techspot.zzzeek.org</uri>
    </author>
    <title type="html"><![CDATA[Akiban-SQLAlchemy - a Webinar]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2012/12/17/akiban-sqlalchemy-a-webinar" />
    <id>http://techspot.zzzeek.org/2012/12/17/akiban-sqlalchemy-a-webinar</id>
    <updated>2012-12-17T17:10:00Z</updated>
    <published>2012-12-17T17:10:00Z</published>
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <summary type="html"><![CDATA[Akiban-SQLAlchemy - a Webinar]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2012/12/17/akiban-sqlalchemy-a-webinar"><![CDATA[<div class="document">
<p>Video is up for the webinar I did for <a class="reference external" href="http://www.akiban.com/">Akiban</a> last Thursday,
where I describe Akiban's interesting take on SQL, as well as a bit about ORM
&quot;eager loading&quot; and how Akiban provides some
intriguing new options in this regard.   Check it out:</p>
<p><a class="reference external" href="http://www.youtube.com/watch?v=G7jInMn_lsY">http://www.youtube.com/watch?v=G7jInMn_lsY</a></p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://techspot.zzzeek.org</uri>
    </author>
    <title type="html"><![CDATA[Pycon Canada - the SQLAlchemy Session In Depth]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2012/11/14/pycon-canada-the-sqlalchemy-session-in-depth" />
    <id>http://techspot.zzzeek.org/2012/11/14/pycon-canada-the-sqlalchemy-session-in-depth</id>
    <updated>2012-11-14T13:31:00Z</updated>
    <published>2012-11-14T13:31:00Z</published>
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <summary type="html"><![CDATA[Pycon Canada - the SQLAlchemy Session In Depth]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2012/11/14/pycon-canada-the-sqlalchemy-session-in-depth"><![CDATA[<div class="document">
<p>Video is up for my <a class="reference external" href="http://pycon.ca/">Pycon.ca</a> talk, <em>The SQLAlchemy Session - In Depth</em>.
In this talk, I delve into the key philosophies behind the design of SQLAlchemy's Session system.
Starting with a brief review of the ACID model, I contrast the approach of the so-called &quot;active record&quot;
pattern to that of the more explicit Session pattern, and how the two approaches integrate with the
ACID model at work within a relational database.   Afterwards, I present an HTML animation of a Session
object at work.</p>
<ul class="simple">
<li><a class="reference external" href="http://pyvideo.org/video/1600/the-sqlalchemy-session-in-depth">Video</a> (setting the quality to 480p is recommended)</li>
<li><a class="reference external" href="/files/2012/session.key.pdf">Slides</a> (pdf format)</li>
<li><a class="reference external" href="/files/2012/session.html.tar.gz">HTML Demo</a> (tar.gz)</li>
</ul>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://techspot.zzzeek.org</uri>
    </author>
    <title type="html"><![CDATA[Supporting a (Very Interesting) New Database]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2012/10/25/supporting-a-very-interesting-new-database" />
    <id>http://techspot.zzzeek.org/2012/10/25/supporting-a-very-interesting-new-database</id>
    <updated>2012-10-26T00:12:35Z</updated>
    <published>2012-10-26T00:12:35Z</published>
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <summary type="html"><![CDATA[Supporting a (Very Interesting) New Database]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2012/10/25/supporting-a-very-interesting-new-database"><![CDATA[<div class="document">
<p>As SQLAlchemy 0.8 nears its first beta release, possibly within the week, lots of new features and additions became apparent as the development cycle went on.   One area that saw more activity than usual was in the area of new dialects.  Going forward, SQLAlchemy will be much more capable of supporting externally-installed dialects, thanks to a new testing suite.  The motiviation for this new suite started when I was tasked with supporting a new and very interesting database vendor.</p>
<div class="section" id="a-late-add">
<h1>A Late Add</h1>
<p>I was approached some months ago by a vendor known as <a class="reference external" href="http://akiban.com/">Akiban</a>, with a request that was totally new to me.  On the initial emails, the idea seemed to be some kind of database that can produce JSON documents from tables, which by itself didn't seem at all very novel; there are already products like <a class="reference external" href="http://htsql.org/">HTSQL</a> and <a class="reference external" href="http://www.slashdb.com/">SlashDB</a> (friend of SQLAlchemy!) which provide RESTful services around relational databases.</p>
<p>But digging in, it became apparent that this company was taking a much more elaborate path to that goal - this company is producing their own relational database from scratch.  The server itself, Akiban server, is written in Java and is designed to act in large part like Postgresql, with some MySQL compatibility added in as well.   Within the span of this obviously monumental task, they have built what seems to be exactly one twist, but it is a really interesting twist, which they call a &quot;table grouping&quot;.</p>
<p>I was very flattered that Akiban not only wanted me to provide SQLAlchemy support for their database, but to help them come up with their Python DBAPI story overall.  And, they wanted not just a SQLAlchemy dialect and Python DBAPI story, they also wanted my thoughts on how modern ORMs can integrate with the unique features of this system.</p>
<p>The reason all three of these areas are up for grabs with Akiban, is that while it acts pretty much like a regular relational database most of the time, it does something strange when the &quot;table grouping&quot; idea is in use.   At the DDL level, a &quot;table grouping&quot; is established just like a foreign key:</p>


<div class="pygments_manni"><pre><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">customer</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">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">cust_order</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">customer_id</span> <span class="nb">INTEGER</span><span class="p">,</span>
    <span class="n">ordernum</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">timestamp</span> <span class="n">DATETIME</span><span class="p">,</span>
    <span class="k">GROUPING</span> <span class="k">FOREIGN</span> <span class="k">KEY</span> <span class="p">(</span><span class="n">customer_id</span><span class="p">)</span> <span class="k">REFERENCES</span> <span class="n">customer</span>
<span class="p">)</span>
</pre></div>



<p>This single keyword on <tt class="docutils literal">GROUPING</tt> causes Akiban to organize the data in a way I don't think any other database does, which is that it stores the rows for <tt class="docutils literal">cust_order</tt> <em>interleaved</em> within those of <tt class="docutils literal">customer</tt>.  Meaning, it stores the data hierarchically, on disk.   This special hierarchy is then made available through SQL.   This is the second part that is really surprising, which is in order to support this, there were no changes at all needed to the SQL syntax.   The only change made to SQL was a <em>semantic</em> one.</p>
<p>Normally, SQL allows us to query for a correlated SELECT in the columns or WHERE clause of a SELECT statement:</p>


<div class="pygments_manni"><pre><span class="k">SELECT</span> <span class="n">name</span><span class="p">,</span> <span class="p">(</span>
                <span class="k">SELECT</span> <span class="n">ordernum</span>
                <span class="k">FROM</span> <span class="n">cust_order</span>
                <span class="k">WHERE</span> <span class="n">customer_id</span><span class="o">=</span><span class="n">customer</span><span class="p">.</span><span class="n">id</span>
                <span class="k">AND</span> <span class="n">ordernum</span> <span class="k">like</span> <span class="s1">&#39;order1%&#39;</span>
        <span class="p">)</span> <span class="k">AS</span> <span class="n">ordernum</span>
<span class="k">FROM</span> <span class="n">customer</span>
</pre></div>



<p>The correlated SELECT must return exactly one column, and one row, or your database will complain.   Here, Akiban merely took away the &quot;complain&quot; part, and when specifying a correlated subquery with multiple columns and potentially multiple rows, you instead get back a result that is hierarchical, assuming the tables you're embedding are related to the parent via a &quot;grouping&quot; - the &quot;nested&quot; rows are fetched in groups along with each corresponding parent row, and delivered inline.   We would get such a result from Akiban given a statement like that below:</p>


<div class="pygments_manni"><pre><span class="k">SELECT</span> <span class="n">name</span><span class="p">,</span> <span class="p">(</span>
                <span class="k">SELECT</span> <span class="n">ordernum</span><span class="p">,</span> <span class="k">timestamp</span>
                <span class="k">FROM</span> <span class="n">cust_order</span>
                <span class="k">WHERE</span> <span class="n">customer_id</span><span class="o">=</span><span class="n">customer</span><span class="p">.</span><span class="n">id</span>
        <span class="p">)</span> <span class="k">AS</span> <span class="n">orders</span>
<span class="k">FROM</span> <span class="n">customer</span>
</pre></div>



<p>But what does a &quot;hierarchical&quot; result look like?  Well, for Akiban, since they wanted this to all work over the Postgresql protocol, for now they actually send you back a JSON string per parent row, as one column.  Such as this:</p>


<div class="pygments_manni"><pre>{&quot;name&quot;:&quot;Some Customer&quot;, &quot;orders&quot;:[{&quot;ordernum&quot;:&quot;some order&quot;, &quot;timestamp&quot;:&quot;20121005121700&quot;}, {&quot;ordernum&quot;:&quot;some other order&quot;, &quot;timestamp&quot;:&quot;20121012184507&quot;}]}
</pre></div>



<p>With that, Akiban asked me what I can do with this.  Particularly, how can an ORM like SQLAlchemy take advantage of it?</p>
</div>
<div class="section" id="well-it-s-just-nested">
<h1>well it's just nested</h1>
<p>The first thing I wanted to do with this data was to make that JSON look like a regular SQL result again.   Having worked with &quot;eager loading&quot; for so many years, I already tend to see SQL products as &quot;hierarchies&quot; - a regular JOIN of customer and order would have rows like:</p>


<div class="pygments_manni"><pre>customer.name        ordernum            timestamp
-------------        ----------------    --------------
Some Customer        some order          20121005121700
Some Customer        some other order    20121012184507
Some Other Customer  ...                 ...
</pre></div>



<p>The result set from a correlated subquery on a &quot;grouped&quot; foreign key, in my mind, looks pretty similar:</p>


<div class="pygments_manni"><pre>customer.name        orders
-------------        ----------------------------------
Some Customer        ordernum            timestamp
                     ----------------    --------------
                     some order          20121005121700
                     some other order    20121012184507
Some Other Customer  ...                 ...
</pre></div>



<p>When we normally have a subquery in the &quot;columns&quot; clause of a SELECT, the result of that SELECT comes back as a single result set column.  My idea was that just as they don't have to change the syntax of SQL to express a &quot;grouping&quot; here, we didn't have to change the idea on the result side either - we just have a <strong>nested cursor</strong>, where a single result set column <tt class="docutils literal">orders</tt> returns a new cursor as its value.</p>
<p>I initially studied Postgresql's protocol quite a bit, mostly by reading the source to the pure-Python <a class="reference external" href="http://pybrary.net/pg8000/">pg8000</a> DBAPI for Postgresql, and proposed to Akiban that they just add some extra messages to the Postgresql protocol to support this concept without the need for JSON being involved.  I could extend or fork pg8000 into a new Akiban-specific DBAPI.   But for the time being, what I ended up doing was to stick with the DBAPI that already works with Akiban, <a class="reference external" href="http://www.initd.org/psycopg/">psycopg2</a>, and extend it on the outside of the JSON to coerce the result back into a cursor shape.   With psycopg2's very extensible design, I was able to make use of its Connection extension system to intercept JSON-formatted results back into cursor-like results, as well as to reuse its existing typing system in order to apply the same string interception it uses on raw Postgresql messages to the JSON-encoded fields as well.   The result of this stage of the game is <a class="reference external" href="https://github.com/zzzeek/akiban_python">Akiban for Python</a>, an extension to psycopg2 that introduces a new result-row datatype, the nested cursor, which is transparently returned when you emit an Akiban &quot;nested&quot; SQL statement - the presense of JSON is entirely concealed.</p>
</div>
<div class="section" id="turtles-all-the-way-down-or-up-in-this-case">
<h1>turtles all the way down (or up, in this case)</h1>
<p>With a DBAPI providing nested cursors, the next task was an Akiban dialect for SQLAlchemy which can wrap these nested cursors into SQLAlchemy's cursor-wrapping <tt class="docutils literal">ResultProxy</tt> object.  Over the years, I've had to make <tt class="docutils literal">ResultProxy</tt> objects deal with so many curveballs, from cx_Oracle's streaming LOB objects and OUT parameters, to the buffering required with psycopg2's &quot;server side cursors&quot;, to pysqlite's quirk with column name descriptions being prepended with the table name when the SQL statement is a UNION of two SELECT statements, that this task was relatively easy to get going.   Slightly more tricky was to get the statement compiler to keep track of &quot;nested&quot; <tt class="docutils literal">select()</tt> constructs and to relate them to the nested cursors ultimately produced.  The end result is that we can build an Akiban nested query and get its results:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">sqlalchemy_akiban</span> <span class="kn">import</span> <span class="n">nested</span>

<span class="n">stmt</span> <span class="o">=</span> <span class="n">nested</span><span class="p">([</span><span class="n">order</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">ordernum</span><span class="p">,</span> <span class="n">order</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">timestamp</span><span class="p">])</span><span class="o">.</span>\
            <span class="n">where</span><span class="p">(</span><span class="n">order</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">customer_id</span> <span class="o">==</span> <span class="n">customer</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
<span class="n">stmt</span> <span class="o">=</span> <span class="n">select</span><span class="p">([</span><span class="n">customer</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">stmt</span><span class="o">.</span><span class="n">label</span><span class="p">(</span><span class="s">&#39;orders&#39;</span><span class="p">)])</span>

<span class="k">for</span> <span class="n">customer_row</span> <span class="ow">in</span> <span class="n">connection</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">stmt</span><span class="p">):</span>
    <span class="k">print</span> <span class="s">&quot;customer name:&quot;</span><span class="p">,</span> <span class="n">customer_row</span><span class="p">[</span><span class="s">&#39;name&#39;</span><span class="p">]</span>
    <span class="k">for</span> <span class="n">order_row</span> <span class="ow">in</span> <span class="n">customer_row</span><span class="p">[</span><span class="s">&#39;orders&#39;</span><span class="p">]:</span>
        <span class="k">print</span> <span class="s">&quot;ordernum:&quot;</span><span class="p">,</span> <span class="n">order_row</span><span class="p">[</span><span class="s">&#39;ordernum&#39;</span><span class="p">]</span>
        <span class="k">print</span> <span class="s">&quot;timestamp:&quot;</span><span class="p">,</span> <span class="n">order_row</span><span class="p">[</span><span class="s">&#39;timestamp&#39;</span><span class="p">]</span>
</pre></div>



<p>And with the above, all of the usual SQLAlchemy Core capabilities like result-set typing and column targeting work out the same.   At the ORM level, I added similar nesting features into <tt class="docutils literal">Query</tt> (meaning, you can get back nested tuples) and also produced a new &quot;loader strategy&quot; specific for &quot;Akiban&quot; style loading on relationships, so that a &quot;nested&quot; cursor can provide for the simplest eager loading implementation ever.  The familiar syntax we use with <tt class="docutils literal">joinedload()</tt> and <tt class="docutils literal">subqueryload()</tt> gets the addition of <tt class="docutils literal">nestedload()</tt>, which we drop in in the same way:</p>


<div class="pygments_manni"><pre><span class="kn">from</span> <span class="nn">sqlalchemy_akiban.orm</span> <span class="kn">import</span> <span class="n">nestedload_all</span>

<span class="n">result</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">Customer</span><span class="p">)</span><span class="o">.</span><span class="n">options</span><span class="p">(</span>
                    <span class="n">orm</span><span class="o">.</span><span class="n">nestedload_all</span><span class="p">(</span><span class="n">Customer</span><span class="o">.</span><span class="n">orders</span><span class="p">,</span> <span class="n">Order</span><span class="o">.</span><span class="n">items</span><span class="p">))</span><span class="o">.</span>\
                        <span class="nb">filter</span><span class="p">(</span><span class="n">Customer</span><span class="o">.</span><span class="n">id</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span>
</pre></div>



<p>Above, the <tt class="docutils literal">Customer.orders</tt> and <tt class="docutils literal">Order.items</tt> collections are populated directly from nested results, using a single statement that optimizes as fast as a straight select of just the <tt class="docutils literal">customer</tt> table and nothing else:</p>


<div class="pygments_manni"><pre>SELECT customer.id AS customer_id, customer.name AS customer_name,
        (SELECT
            (SELECT item.id, item.order_id, item.price, item.quantity
            FROM item
            WHERE &quot;order&quot;.id = item.order_id
        ) AS anon_2,
        &quot;order&quot;.id, &quot;order&quot;.customer_id, &quot;order&quot;.order_info
        FROM &quot;order&quot;
        WHERE customer.id = &quot;order&quot;.customer_id
) AS anon_1
FROM customer
WHERE customer.id = %(id_1)s
</pre></div>



<p>All of the above was possible with pretty much no changes to SQLAlchemy itself, save for one new dialect hook which allows the cursor context to be available to type objects - since we introduced an extension type called <tt class="docutils literal">NestedResult</tt> which needs more information than most types.  The ORM, compiler, etc. needed no changes.   The result of this stage is available at <a class="reference external" href="https://github.com/zzzeek/sqlalchemy_akiban">SQLAlchemy Akiban</a>.</p>
</div>
<div class="section" id="onward">
<h1>Onward</h1>
<p>In an upcoming post, I'll be describing the new dialect test suite I developed, as a result of my work in supporting the Akiban database.</p>
</div>
<div class="section" id="links">
<h1>Links</h1>
<ul class="simple">
<li><a class="reference external" href="https://github.com/zzzeek/akiban_python">Akiban for Python</a> - Akiban extension for the psycopg2 DBAPI</li>
<li><a class="reference external" href="https://github.com/zzzeek/sqlalchemy_akiban">SQLAlchemy Akiban</a> - Akiban dialect and ORM extension for SQLAlchemy</li>
</ul>
</div>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://techspot.zzzeek.org</uri>
    </author>
    <title type="html"><![CDATA[Pycon 2012 : Hand Coded Applications with SQLAlchemy]]></title>
    <link rel="alternate" type="text/html" href="http://techspot.zzzeek.org/2012/03/12/pycon-2012-hand-coded-applications-with-sqlalchemy" />
    <id>http://techspot.zzzeek.org/2012/03/12/pycon-2012-hand-coded-applications-with-sqlalchemy</id>
    <updated>2012-03-12T16:01:00Z</updated>
    <published>2012-03-12T16:01:00Z</published>
    <category scheme="http://techspot.zzzeek.org" term="SQLAlchemy" />
    <category scheme="http://techspot.zzzeek.org" term="Code" />
    <summary type="html"><![CDATA[Pycon 2012 : Hand Coded Applications with SQLAlchemy]]></summary>
    <content type="html" xml:base="http://techspot.zzzeek.org/2012/03/12/pycon-2012-hand-coded-applications-with-sqlalchemy"><![CDATA[<div class="document">
<p>Here's the <a class="reference external" href="/files/2012/hand_coded_with_sqla.key.pdf">slides</a> from my Pycon
2012 talk, &quot;Hand Coded Applications with SQLAlchemy&quot;. I had a great time with
this talk and thanks all for coming !</p>
<p><strong>Update:</strong>  Here's <a class="reference external" href="http://www.youtube.com/watch?v=E09qigk_hnY">the video!</a></p>
</div>
]]></content>
  </entry>
  <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>
</feed>
