<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <title>zzzeek</title>
    <link>http://techspot.zzzeek.org</link>
    <description>mostly computer stuff</description>
    <pubDate>Fri, 17 May 2013 04:32:10 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Introduction to SQLAlchemy - Pycon 2013 - Wrapup</title>
      <link>http://techspot.zzzeek.org/2013/04/04/introduction-to-sqlalchemy-pycon-2013-wrapup</link>
      <pubDate>Thu, 04 Apr 2013 12:10:00 EDT</pubDate>
      <category><![CDATA[Code]]></category>
      <category><![CDATA[SQLAlchemy]]></category>
      <guid isPermaLink="true">http://techspot.zzzeek.org/2013/04/04/introduction-to-sqlalchemy-pycon-2013-wrapup</guid>
      <description>Introduction to SQLAlchemy - Pycon 2013 - Wrapup</description>
      <content:encoded><![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:encoded>
    </item>
    <item>
      <title>Introduction to SQLAlchemy - Pycon 2013</title>
      <link>http://techspot.zzzeek.org/2013/03/05/introduction-to-sqlalchemy-pycon-2013</link>
      <pubDate>Tue, 05 Mar 2013 12:10:00 EST</pubDate>
      <category><![CDATA[Code]]></category>
      <category><![CDATA[SQLAlchemy]]></category>
      <guid isPermaLink="true">http://techspot.zzzeek.org/2013/03/05/introduction-to-sqlalchemy-pycon-2013</guid>
      <description>Introduction to SQLAlchemy - Pycon 2013</description>
      <content:encoded><![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:encoded>
    </item>
    <item>
      <title>Akiban-SQLAlchemy - a Webinar</title>
      <link>http://techspot.zzzeek.org/2012/12/17/akiban-sqlalchemy-a-webinar</link>
      <pubDate>Mon, 17 Dec 2012 12:10:00 EST</pubDate>
      <category><![CDATA[Code]]></category>
      <category><![CDATA[SQLAlchemy]]></category>
      <guid isPermaLink="true">http://techspot.zzzeek.org/2012/12/17/akiban-sqlalchemy-a-webinar</guid>
      <description>Akiban-SQLAlchemy - a Webinar</description>
      <content:encoded><![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:encoded>
    </item>
    <item>
      <title>Pycon Canada - the SQLAlchemy Session In Depth</title>
      <link>http://techspot.zzzeek.org/2012/11/14/pycon-canada-the-sqlalchemy-session-in-depth</link>
      <pubDate>Wed, 14 Nov 2012 08:31:00 EST</pubDate>
      <category><![CDATA[Code]]></category>
      <category><![CDATA[SQLAlchemy]]></category>
      <guid isPermaLink="true">http://techspot.zzzeek.org/2012/11/14/pycon-canada-the-sqlalchemy-session-in-depth</guid>
      <description>Pycon Canada - the SQLAlchemy Session In Depth</description>
      <content:encoded><![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:encoded>
    </item>
    <item>
      <title>Supporting a (Very Interesting) New Database</title>
      <link>http://techspot.zzzeek.org/2012/10/25/supporting-a-very-interesting-new-database</link>
      <pubDate>Thu, 25 Oct 2012 20:12:35 EDT</pubDate>
      <category><![CDATA[Code]]></category>
      <category><![CDATA[SQLAlchemy]]></category>
      <guid isPermaLink="true">http://techspot.zzzeek.org/2012/10/25/supporting-a-very-interesting-new-database</guid>
      <description>Supporting a (Very Interesting) New Database</description>
      <content:encoded><![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:encoded>
    </item>
    <item>
      <title>The Absolutely Simplest Consistent Hashing Example</title>
      <link>http://techspot.zzzeek.org/2012/07/07/the-absolutely-simplest-consistent-hashing-example</link>
      <pubDate>Sat, 07 Jul 2012 12:01:00 EDT</pubDate>
      <category><![CDATA[Code]]></category>
      <guid isPermaLink="true">http://techspot.zzzeek.org/2012/07/07/the-absolutely-simplest-consistent-hashing-example</guid>
      <description>The Absolutely Simplest Consistent Hashing Example</description>
      <content:encoded><![CDATA[<div class="document">
<p>Lately I've been studying <a class="reference external" href="http://redis.io">Redis</a> a lot.  When using key/value databases
like Redis, as well as caches like <a class="reference external" href="http://memcached.org/">Memcached</a>,
if you want to scale keys across multiple nodes, you need a consistent
hashing algorithm.   Consistent hashing is what we use when we want to distribute
a set of keys along a span of key/value servers in a...well consistent fashion.</p>
<p>If you Google around to learn what consistent hashing means,
the article that most directly tells you &quot;the answer&quot; without
a lot of handwringing is <a class="reference external" href="http://weblogs.java.net/blog/tomwhite/archive/2007/11/consistent_hash.html">Consistent Hashing</a> by Tom White.
Not only does it explain the concept very clearly, it even has a plain and
simple code example in Java.</p>
<p>The recipe in Tom's post is dependent on the capabilities of Java's <tt class="docutils literal">TreeMap</tt>
which we don't have in Python, but after some contemplation it became apparent
that the functionality of <tt class="docutils literal">circle.tailMap(hash)</tt> is something we already
have using <a class="reference external" href="http://docs.python.org/library/bisect.html">bisect</a>, that is, we have a
sorted array of integers, and a new number.  Where in the array does the
new number go?  <tt class="docutils literal">bisect.bisect()</tt> will give you that, with the same efficiency as
<tt class="docutils literal">TreeMap</tt>.</p>
<p>As a sanity check, I searched a bit more for Python implementations.  I found
a recipe by <a class="reference external" href="http://amix.dk/blog/viewEntry/19367">Amir Salihefendic</a>, which
seems to be based on the Java recipe and is pretty nice,
but in the post he's searching the circle for hash values using
a linear search, ouch!  Turns out
Amir is in fact using <tt class="docutils literal">bisect</tt> in his Python Cheese Shop package <a class="reference external" href="http://pypi.python.org/pypi/hash_ring/">hash_ring</a>, but by then it was too late, I had already written my own recipe
as well as tests (which <tt class="docutils literal">hash_ring</tt> doesn't appear to have, at least in the downloaded
distribution).
There's also <a class="reference external" href="http://pypi.python.org/pypi/python-continuum/">Continuum</a>,
taking a slightly more heavy-handed approach (three separate classes and an expensive
<tt class="docutils literal">IndexError</tt> being caught to detect keys beyond the circle).   Both systems, Continuum
more so, seem to encourage using hostnames directly as keys - as noted by
<a class="reference external" href="http://blog.zawodny.com/2011/02/26/redis-sharding-at-craigslist/">Jeremy Zawodny</a>,
with a persistent system like Redis this is a bad idea as it means you can't move
a particular key set to a new host.</p>
<p>So spending a bit of <a class="reference external" href="http://en.wikipedia.org/wiki/Not_invented_here">NIH</a> capital, here's
my recipe, which provides a dictionary interface so that you can store hostnames or even actual
client instances, keyed to symbolic names:</p>


<div class="pygments_manni"><pre><span class="kn">import</span> <span class="nn">bisect</span>
<span class="kn">import</span> <span class="nn">md5</span>

<span class="k">class</span> <span class="nc">ConsistentHashRing</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Implement a consistent hashing ring.&quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">replicas</span><span class="o">=</span><span class="mi">100</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Create a new ConsistentHashRing.</span>

<span class="sd">        :param replicas: number of replicas.</span>

<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">replicas</span> <span class="o">=</span> <span class="n">replicas</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_keys</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_nodes</span> <span class="o">=</span> <span class="p">{}</span>

    <span class="k">def</span> <span class="nf">_hash</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Given a string key, return a hash value.&quot;&quot;&quot;</span>

        <span class="k">return</span> <span class="nb">long</span><span class="p">(</span><span class="n">md5</span><span class="o">.</span><span class="n">md5</span><span class="p">(</span><span class="n">key</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">(),</span> <span class="mi">16</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_repl_iterator</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nodename</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Given a node name, return an iterable of replica hashes.&quot;&quot;&quot;</span>

        <span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_hash</span><span class="p">(</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="n">nodename</span><span class="p">,</span> <span class="n">i</span><span class="p">))</span>
                <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">replicas</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">__setitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nodename</span><span class="p">,</span> <span class="n">node</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Add a node, given its name.</span>

<span class="sd">        The given nodename is hashed</span>
<span class="sd">        among the number of replicas.</span>

<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">for</span> <span class="n">hash_</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_repl_iterator</span><span class="p">(</span><span class="n">nodename</span><span class="p">):</span>
            <span class="k">if</span> <span class="n">hash_</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_nodes</span><span class="p">:</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s">&quot;Node name </span><span class="si">%r</span><span class="s"> is &quot;</span>
                            <span class="s">&quot;already present&quot;</span> <span class="o">%</span> <span class="n">nodename</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_nodes</span><span class="p">[</span><span class="n">hash_</span><span class="p">]</span> <span class="o">=</span> <span class="n">node</span>
            <span class="n">bisect</span><span class="o">.</span><span class="n">insort</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_keys</span><span class="p">,</span> <span class="n">hash_</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__delitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nodename</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Remove a node, given its name.&quot;&quot;&quot;</span>

        <span class="k">for</span> <span class="n">hash_</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_repl_iterator</span><span class="p">(</span><span class="n">nodename</span><span class="p">):</span>
            <span class="c"># will raise KeyError for nonexistent node name</span>
            <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">_nodes</span><span class="p">[</span><span class="n">hash_</span><span class="p">]</span>
            <span class="n">index</span> <span class="o">=</span> <span class="n">bisect</span><span class="o">.</span><span class="n">bisect_left</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_keys</span><span class="p">,</span> <span class="n">hash_</span><span class="p">)</span>
            <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">_keys</span><span class="p">[</span><span class="n">index</span><span class="p">]</span>

    <span class="k">def</span> <span class="nf">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Return a node, given a key.</span>

<span class="sd">        The node replica with a hash value nearest</span>
<span class="sd">        but not less than that of the given</span>
<span class="sd">        name is returned.   If the hash of the</span>
<span class="sd">        given name is greater than the greatest</span>
<span class="sd">        hash, returns the lowest hashed node.</span>

<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">hash_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_hash</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
        <span class="n">start</span> <span class="o">=</span> <span class="n">bisect</span><span class="o">.</span><span class="n">bisect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_keys</span><span class="p">,</span> <span class="n">hash_</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">start</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_keys</span><span class="p">):</span>
            <span class="n">start</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_nodes</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_keys</span><span class="p">[</span><span class="n">start</span><span class="p">]]</span>
</pre></div>



<p>The map is used as a dictionary of node names to whatever you want, such as here we use Redis clients:</p>


<div class="pygments_manni"><pre><span class="kn">import</span> <span class="nn">redis</span>
<span class="n">cr</span> <span class="o">=</span> <span class="o">=</span> <span class="n">ConsistentHashRing</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>

<span class="n">cr</span><span class="p">[</span><span class="s">&quot;node1&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">redis</span><span class="o">.</span><span class="n">StrictRedis</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="s">&quot;host1&quot;</span><span class="p">)</span>
<span class="n">cr</span><span class="p">[</span><span class="s">&quot;node2&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">redis</span><span class="o">.</span><span class="n">StrictRedis</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="s">&quot;host2&quot;</span><span class="p">)</span>

<span class="n">client</span> <span class="o">=</span> <span class="n">cr</span><span class="p">[</span><span class="s">&quot;some key&quot;</span><span class="p">]</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;some key&quot;</span><span class="p">)</span>
</pre></div>



<p>I wanted to validate that the ring is in fact producing standard deviations like
those mentioned in the Java article, so this is tested like the following:</p>


<div class="pygments_manni"><pre><span class="kn">import</span> <span class="nn">unittest</span>
<span class="kn">import</span> <span class="nn">collections</span>
<span class="kn">import</span> <span class="nn">random</span>
<span class="kn">import</span> <span class="nn">math</span>

<span class="k">class</span> <span class="nc">ConsistentHashRingTest</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">test_get_distribution</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">ring</span> <span class="o">=</span> <span class="n">ConsistentHashRing</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>

        <span class="n">numnodes</span> <span class="o">=</span> <span class="mi">10</span>
        <span class="n">numhits</span> <span class="o">=</span> <span class="mi">1000</span>
        <span class="n">numvalues</span> <span class="o">=</span> <span class="mi">10000</span>

        <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">numnodes</span><span class="p">):</span>
            <span class="n">ring</span><span class="p">[</span><span class="s">&quot;node</span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;node_value</span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">i</span>

        <span class="n">distributions</span> <span class="o">=</span> <span class="n">collections</span><span class="o">.</span><span class="n">defaultdict</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="n">numhits</span><span class="p">):</span>
            <span class="n">key</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">numvalues</span><span class="p">))</span>
            <span class="n">node</span> <span class="o">=</span> <span class="n">ring</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
            <span class="n">distributions</span><span class="p">[</span><span class="n">node</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>

        <span class="c"># count of hits matches what is observed</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span><span class="nb">sum</span><span class="p">(</span><span class="n">distributions</span><span class="o">.</span><span class="n">values</span><span class="p">()),</span> <span class="n">numhits</span><span class="p">)</span>

        <span class="c"># I&#39;ve observed standard deviation for 10 nodes + 100</span>
        <span class="c"># replicas to be between 10 and 15.   Play around with</span>
        <span class="c"># the number of nodes / replicas to see how different</span>
        <span class="c"># tunings work out.</span>
        <span class="n">standard_dev</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pop_std_dev</span><span class="p">(</span><span class="n">distributions</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">assertLessEqual</span><span class="p">(</span><span class="n">standard_dev</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span>

        <span class="c"># if the stddev is good, it&#39;s safe to assume</span>
        <span class="c"># all nodes were used</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">distributions</span><span class="p">),</span> <span class="n">numnodes</span><span class="p">)</span>

        <span class="c"># just to test getting keys, see that we got the values</span>
        <span class="c"># back and not keys or indexes or whatever.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">assertEquals</span><span class="p">(</span>
                <span class="nb">set</span><span class="p">(</span><span class="n">distributions</span><span class="o">.</span><span class="n">keys</span><span class="p">()),</span>
                <span class="nb">set</span><span class="p">(</span><span class="s">&quot;node_value</span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span> <span class="o">+</span> <span class="n">numnodes</span><span class="p">))</span>
            <span class="p">)</span>

    <span class="k">def</span> <span class="nf">_pop_std_dev</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">population</span><span class="p">):</span>
        <span class="n">mean</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">population</span><span class="p">)</span> <span class="o">/</span> <span class="nb">len</span><span class="p">(</span><span class="n">population</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">math</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span>
                <span class="nb">sum</span><span class="p">(</span><span class="nb">pow</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="n">mean</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">population</span><span class="p">)</span>
                <span class="o">/</span> <span class="nb">len</span><span class="p">(</span><span class="n">population</span><span class="p">)</span>
            <span class="p">)</span>
</pre></div>



</div>
]]></content:encoded>
    </item>
    <item>
      <title>Server Side Templates and API Centric Development</title>
      <link>http://techspot.zzzeek.org/2012/06/18/server-side-templates-and-api-centric-development</link>
      <pubDate>Mon, 18 Jun 2012 12:01:00 EDT</pubDate>
      <category><![CDATA[Mako]]></category>
      <category><![CDATA[Code]]></category>
      <guid isPermaLink="true">http://techspot.zzzeek.org/2012/06/18/server-side-templates-and-api-centric-development</guid>
      <description>Server Side Templates and API Centric Development</description>
      <content:encoded><![CDATA[<div class="document">
<p>We're here to talk about the rise of the API-focused application, and how it
interacts with templates for rendering HTML for web browsers.   The simple point I hope
to make is: you don't necessarily need to use all client side templates in order
to write an effective API-centric web application.</p>
<p>I'll do this by illustrating a simple web application, with a single
API-oriented method (that is, returns
JSON-oriented data), where the way it's rendered and the style of template
in use is entirely a matter of declarative configuration.  Rendering of
full pages as well as Ajax delivered &quot;fragments&quot; are covered using both
server- and client-side rendering approaches.</p>
<div class="section" id="api-centric-development">
<h1>API Centric Development</h1>
<p>Most dynamic web applications we write today have the requirement that they
provide APIs - that is, methods which return pure data for the consumption by
a wide variety of clients.   The trend here is towards organizing web applications
from the start to act like APIs.   In a nutshell, it means we are moving
away from mode of data models injected into templates:</p>


<div class="pygments_manni"><pre><span class="k">def</span> <span class="nf">get_balance</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="n">balance</span> <span class="o">=</span> <span class="n">BankBalance</span><span class="p">(</span>
        <span class="n">amount</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="n">currency</span><span class="o">=</span><span class="s">&quot;euro&quot;</span><span class="p">),</span>
        <span class="n">as_of_date</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">(</span><span class="mi">2012</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">14</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
    <span class="p">)</span>
    <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">&quot;balance.html&quot;</span><span class="p">,</span> <span class="n">balance</span><span class="o">=</span><span class="n">balance</span><span class="p">)</span>
</pre></div>



<p>and instead towards returning JSON-compatible data structures, with
the &quot;view&quot; being decided somewhere else:</p>


<div class="pygments_manni"><pre><span class="nd">@view_config</span><span class="p">(</span><span class="s">&#39;balance&#39;</span><span class="p">,</span> <span class="n">renderer</span><span class="o">=</span><span class="s">&#39;json&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">balance</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="k">return</span> <span class="p">{</span>
        <span class="s">&#39;amount&#39;</span><span class="p">:</span><span class="mi">10000</span><span class="p">,</span>
        <span class="s">&#39;currency&#39;</span><span class="p">:</span><span class="s">&#39;euro&#39;</span><span class="p">,</span>
        <span class="s">&#39;as_of_date&#39;</span><span class="p">:</span><span class="s">&#39;2012-06-14 14:12:00&#39;</span>
    <span class="p">}</span>
</pre></div>



<p>This is a fine trend, allowing us to make a clearer line between server side concepts
and rendering concepts, and giving us an API-centric view of our data from day one.</p>
</div>
<div class="section" id="templates">
<h1>Templates</h1>
<p>There's a misunderstanding circulating about API-centric development which says that we have to
use client side templates:</p>
<blockquote>
API-centric development. If you take a client-side rendering approach, odds
are the server side of your web application is going to look more like an API
than it would if you were doing entirely server-side rendering. And if/when
you have plans to release an API, you'd probably already be 90% of the way
there. (<a class="reference external" href="http://openmymind.net/2012/5/30/Client-Side-vs-Server-Side-Rendering/#comment-544974348">http://openmymind.net/2012/5/30/Client-Side-vs-Server-Side-Rendering/#comment-544974348</a>)</blockquote>
<p>and:</p>
<blockquote>
Lastly, another issue i can see, assuming you develop using MVC. You need
to have the view, model and controller very tightly coupled to make his
way work. The controller needs to know how the view works to create html
that can slot right in. It's easier if the controller only has to pass
data, not layout information.
(<a class="reference external" href="http://www.reddit.com/r/programming/comments/ufyf3/clientside_vs_serverside_rendering/c4v5vjb">http://www.reddit.com/r/programming/comments/ufyf3/clientside_vs_serverside_rendering/c4v5vjb</a>)</blockquote>
<p>This second quote is specific to the approach of delivering rendered HTML
in an ajax response, to be directly rendered into a DOM element, which we will also demonstrate here.
How the &quot;model&quot; is more tightly coupled to anything when you have a
server side vs client side template, I have absolutely no idea.</p>
<p>Why might we want to stick with server side templates?   As a Python
developer, in my view the main
reason is that they are still a lot easier to develop with,
assuming we aren't developing our server in Javascript as well.
Consider if our bank account balance needed locale-specific
number, currency and date formatting, and also needed to convert the timestamp
from UTC into a preferred timezone.   A server side approach allows us to easily inject
more functionality into our template as part of its standard environment
for all render calls, such as something
like this:</p>


<div class="pygments_manni"><pre><span class="k">def</span> <span class="nf">render_template</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">template</span><span class="p">,</span> <span class="o">**</span><span class="n">template_ns</span><span class="p">):</span>
    <span class="n">number_formatter</span> <span class="o">=</span> <span class="n">number_formatter</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">preferred_locale</span><span class="p">)</span>
    <span class="n">template_ns</span><span class="p">[</span><span class="s">&#39;currency_format&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">currency_formatter</span><span class="p">(</span><span class="n">number_formatter</span><span class="p">)</span>
    <span class="n">template_ns</span><span class="p">[</span><span class="s">&#39;date_format&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">date_formatter</span><span class="p">(</span>
                                <span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">preferred_timezone</span><span class="p">,</span>
                                <span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">preferred_date_format</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">lookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="n">template</span><span class="p">)</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="o">**</span><span class="n">template_ns</span><span class="p">)</span>
</pre></div>



<p>The template can, if it needs to, call upon these methods like this:</p>


<div class="pygments_manni"><pre><span class="x">&lt;ul&gt;</span>
<span class="x">    &lt;li&gt;Balance: </span><span class="cp">${</span><span class="n">data</span><span class="p">[</span><span class="s">&#39;amount&#39;</span><span class="p">]</span> <span class="o">|</span> <span class="n">currency_format</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="s">&#39;currency&#39;</span><span class="p">])</span><span class="cp">}</span><span class="x">&lt;/li&gt;</span>
<span class="x">    &lt;li&gt;As of: </span><span class="cp">${</span><span class="n">data</span><span class="p">[</span><span class="s">&#39;as_of_date&#39;</span><span class="p">]</span> <span class="o">|</span> <span class="n">date_format</span><span class="cp">}</span><span class="x">&lt;/li&gt;</span>
<span class="x">&lt;/ul&gt;</span>
</pre></div>



<p>With a client side template, we have to implement all of <tt class="docutils literal">currency_formatter</tt>,
<tt class="docutils literal">number_formatter</tt>, <tt class="docutils literal">date_formatter</tt> in Javascript.   These methods
may need to respond to business-specific inputs, such as specific user preferences
or other rules, that also need to be pushed up to the client.   All the additional Javascript
logic we're pushing out to the client brings forth the need for it to be unit
tested, which so far means we need to add significant complexity to the testing
environment by running
a Javascript engine like node.js or something else in order to test all this
functionality.   Remember, we're not already using node.js
to do the whole thing.  If we were, then yes everything is different, but I wasn't planning on abandoning
Python for web development just yet.</p>
<p>Some folks might argue that elements like date conversion and number formatting should
still remain on the server, but just be applied by the API to the data
being returned directly.  To me, this is specifically the worst thing you can
do - it basically means that the client side approach is forcing you to
move presentation-level concepts directly into your API's data format.
Almost immediately, you'll find yourself having to inject HTML entities for
currency symbols and other browser-specific markup into this data, at the very
least complicating your API with presentational concerns and in the worst case
pretty much ruining the purity of your API data.   While the examples here may
be a little contrived, you can be sure that more intricate cases come up
in practice that present an ongoing stream of hard decisions between complicating/polluting
server-generated API data with presentation concepts versus building a much heavier client
than initially seemed necessary.</p>
<p>Also, what about performance?  Don't client side/server side templates perform/scale/respond
worse/better?   My position here is &quot;if we're just starting out, then who knows, who cares&quot;.
If I've built an application
and I've observed that its responsiveness or scalability would benefit from some areas switching
to client side rendering, then that's an optimization that can be made later.
We've seen big sites like <a class="reference external" href="http://engineering.linkedin.com/frontend/leaving-jsps-dust-moving-linkedin-dustjs-client-side-templates">LinkedIn switch from server to client side rendering</a>,
and <a class="reference external" href="http://engineering.twitter.com/2012/05/improving-performance-on-twittercom.html">Twitter switch from client to server side rendering</a>,
both in the name of &quot;performance&quot;!
Who knows!  Overall, I don't think the difference between pushing out json strings versus HTML fragments
is something that warrants concern up front, until the application is more fully
formed and specific issues can addressed as needed.</p>
</div>
<div class="section" id="the-alternative">
<h1>The Alternative</h1>
<p>Implementing a larger client-side application than we might have originally
preferred is all doable of course, but given the additional steps of building
a bootstrap system for a pure client-side approach, reimplementing lots of
Python functionality, in some cases significant tasks such as timezone conversion,
into Javascript, and figuring out how to unit test it all, is a lot
of trouble for something that is pretty much effortless in a server side system -
must we go all client-side in order to be API centric?</p>
<p>Of course not!</p>
<p>The example I've produced illustrates a single, fake API method that produces a grid
of random integers:</p>


<div class="pygments_manni"><pre><span class="nd">@view_config</span><span class="p">(</span><span class="n">route_name</span><span class="o">=</span><span class="s">&#39;api_ajax&#39;</span><span class="p">,</span> <span class="n">renderer</span><span class="o">=</span><span class="s">&#39;json&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">api</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="k">return</span> <span class="p">[</span>
        <span class="p">[</span><span class="s">&quot;</span><span class="si">%0.2d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">99</span><span class="p">)</span>  <span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">10</span><span class="p">)]</span>
        <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
    <span class="p">]</span>
</pre></div>



<p>and delivers it in four ways - two use server side rendering, two use client
side rendering.   Only <strong>one</strong> client template and <strong>one</strong> server side template
is used, and there is only <strong>one</strong> API call, which internally knows nothing
whatsoever about how it is displayed.  Basically, the design of our server component is un-impacted
by what style of rendering we use, save for different routing declarations
which we'll see later.</p>
<p>For client side rendering of this data, we'll use a <a class="reference external" href="http://handlebarsjs.com/">handlebars.js</a>
template:</p>


<div class="pygments_manni"><pre><span class="nt">&lt;p&gt;</span>
    API data -
    {{#if is_page}}
        Displayed via server-initiated, client-rendered page
    {{/if}}
    {{#unless is_page}}
        Displayed via client-initiated, client-rendered page
    {{/unless}}
<span class="nt">&lt;/p&gt;</span>

<span class="nt">&lt;table&gt;</span>
    {{#each data}}
        <span class="nt">&lt;tr&gt;</span>
            {{#each this}}
                <span class="nt">&lt;td&gt;</span>{{this}}<span class="nt">&lt;/td&gt;</span>
            {{/each}}
        <span class="nt">&lt;/tr&gt;</span>
    {{/each}}
<span class="nt">&lt;/table&gt;</span>
</pre></div>



<p>and for server side rendering, we'll use a <a class="reference external" href="http://www.makotemplates.org">Mako</a> template:</p>


<div class="pygments_manni"><pre><span class="cp">&lt;%</span><span class="nb">inherit</span> <span class="na">file=</span><span class="s">&quot;layout.mako&quot;</span><span class="cp">/&gt;</span><span class="x"></span>

<span class="cp">${</span><span class="n">display_api</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>

<span class="cp">&lt;%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">&quot;display_api(inline=False)&quot;</span><span class="cp">&gt;</span><span class="x"></span>
<span class="x">    &lt;p&gt;</span>
<span class="x">        API data -</span>
        <span class="cp">%</span> <span class="k">if</span> <span class="n">inline</span><span class="p">:</span><span class="x"></span>
<span class="x">            Displayed inline within a server-rendered page</span>
        <span class="cp">%</span> <span class="k">else</span><span class="p">:</span><span class="x"></span>
<span class="x">            Displayed via server-rendered ajax call</span>
        <span class="cp">%</span><span class="k"> endif</span><span class="x"></span>
<span class="x">    &lt;/p&gt;</span>
<span class="x">    &lt;table&gt;</span>
        <span class="cp">%</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span><span class="x"></span>
<span class="x">            &lt;tr&gt;</span>
                <span class="cp">%</span> <span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="n">row</span><span class="p">:</span><span class="x"></span>
<span class="x">                    &lt;td&gt;</span><span class="cp">${</span><span class="n">col</span><span class="cp">}</span><span class="x">&lt;/td&gt;</span>
                <span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
<span class="x">            &lt;/tr&gt;</span>
        <span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
<span class="x">    &lt;/table&gt;</span>
<span class="cp">&lt;/%</span><span class="nb">def</span><span class="cp">&gt;</span><span class="x"></span>
</pre></div>



<p>The Mako template is using a <tt class="docutils literal">&lt;%def&gt;</tt> to provide indirection between the rendering
of the full page, and the rendering of the API data.  This is not a requirement,
but is here because we'll be illustrating also
how to dual purpose a single Mako template such that part of it can be used for a traditional
full page render as well as for an ajax-delivered HTML fragment, with no duplication.  It's
essentially a Pyramid port of the same technique I illustrated with Pylons four years ago
in my post <a class="reference external" href="/2008/09/01/ajax-the-mako-way/">Ajax the Mako Way</a>, which appears to
be somewhat forgotten.  Among other things, Pyramid's Mako renderer does not appear integrate
the capability to call upon page defs directly, even though
I had successfully lobbied to get the critical <tt class="docutils literal">render_def()</tt> into its predecessor
Pylons.  Here, I've implemented my own Mako renderer for Pyramid.</p>
<p>Key here is that we are separating the concept
of how the API interface is constructed, versus what the server actually produces.
Above, note we're using the Pyramid &quot;json&quot; renderer for our API data.
Note the term &quot;renderer&quot;.   Interpreting our API method as a JSON API,
as a call to a specific client-side template plus JSON API, or as a server
side render or ajax call is just a matter of declaration.   The way we
organize our application in an API-centric fashion has <em>nothing to do</em>
with where the rendering takes place.   To illustrate four different ways
of interpreting the same API method, we just need to add four different
<tt class="docutils literal">&#64;view_config</tt> directives:</p>


<div class="pygments_manni"><pre><span class="nd">@view_config</span><span class="p">(</span><span class="n">route_name</span><span class="o">=</span><span class="s">&#39;server_navigate&#39;</span><span class="p">,</span> <span class="n">renderer</span><span class="o">=</span><span class="s">&#39;home.mako&#39;</span><span class="p">)</span>
<span class="nd">@view_config</span><span class="p">(</span><span class="n">route_name</span><span class="o">=</span><span class="s">&#39;server_ajax&#39;</span><span class="p">,</span> <span class="n">renderer</span><span class="o">=</span><span class="s">&#39;home|display_api.mako&#39;</span><span class="p">)</span>
<span class="nd">@view_config</span><span class="p">(</span><span class="n">route_name</span><span class="o">=</span><span class="s">&#39;client_navigate&#39;</span><span class="p">,</span> <span class="n">renderer</span><span class="o">=</span><span class="s">&#39;display_api.handlebars&#39;</span><span class="p">)</span>
<span class="nd">@view_config</span><span class="p">(</span><span class="n">route_name</span><span class="o">=</span><span class="s">&#39;api_ajax&#39;</span><span class="p">,</span> <span class="n">renderer</span><span class="o">=</span><span class="s">&#39;json&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">api</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="k">return</span> <span class="p">[</span>
        <span class="p">[</span><span class="s">&quot;</span><span class="si">%0.2d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">99</span><span class="p">)</span>  <span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">10</span><span class="p">)]</span>
        <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
    <span class="p">]</span>
</pre></div>



<p>The rendering methods here are as follows:</p>
<ul class="simple">
<li><strong>Method One, Server Via Server</strong> - The <tt class="docutils literal">api()</tt> view method returns the data, which
is received by the <tt class="docutils literal">home.mako</tt> template, which renders the full page,
and passes the data to the <tt class="docutils literal">display_api()</tt> def within the same
phase for all-at-once server side rendering.</li>
<li><strong>Method Two, Server Via Client</strong> - A hyperlink on the page initiates
an ajax call to the server's <tt class="docutils literal">server_ajax</tt> route, which invokes the
<tt class="docutils literal">api()</tt> view method, and returns the data directly to the <tt class="docutils literal">display_api</tt>
def present in the <tt class="docutils literal">home.mako</tt> template.   For this case, I had to
create my own Pyramid Mako renderer that receives a custom syntax,
where the page name and def name are separated by a pipe character.</li>
<li><strong>Method Three, Client Via Server</strong> - Intrinsic to any client side rendered
approach is that the server needs to first deliver some kind of HTML layout,
as nothing more than a launching point for all the requisite javascript
needed to start rendering the page for real.  This method illustrates that,
by delivering the <tt class="docutils literal">handlebars_base.mako</tt> template which serves as the
bootstrap point for any server-initiated page call that renders with
a client side template.   In this mode, it also embeds the data
returned by <tt class="docutils literal">api()</tt> within the &lt;script&gt; tags at the top of the page,
and then invokes the Javascript application to render the
<tt class="docutils literal">display_api.handlebars</tt> template, providing it with the embedded data.
Another approach here might be to deliver the template in one call, and
to have the client invoke the <tt class="docutils literal">api()</tt> method as a separate ajax call,
though this takes two requests instead of one and also implies adding
another server-side view method.</li>
<li><strong>Method Four, Client Via Client</strong> - A hyperlink on the page illustrates
how a client-rendered application can navigate to a certain view,
calling upon the server only for raw data (and possibly the client
side template itself, until its cached in a client-side collection).
The link includes
additional attributes which allow the javascript application to call
upon the <tt class="docutils literal">display_api.handlebars</tt> template directly, and renders it
along with the data returned by calling the <tt class="docutils literal">api()</tt> view method
with the <tt class="docutils literal">json</tt> renderer.</li>
</ul>
<p>Credit goes to Chris Rossi for coming up with the original client-side
rendering techniques that I've adapted here.</p>
<p>A screen shot of what we're looking at is as follows:</p>
<div class="figure">
<img alt="Template Demo Screenshot" src="/files/2012/template_demo_screenshot.png" />
</div>
<p>The demonstration here is hopefully useful not just to illustrate the server
techniques I'm talking about, but also as a way to play around with client
side rendering as well, including mixing and matching both server and client
side rendering together.   The hybrid approach is where I predict most
applications will be headed.</p>
<p>You can pull out the demo using git at <a class="reference external" href="https://bitbucket.org/zzzeek/client_template_demo">https://bitbucket.org/zzzeek/client_template_demo</a>.
Enjoy !</p>
</div>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Using Beaker for Caching?  Why You'll Want to Switch to dogpile.cache</title>
      <link>http://techspot.zzzeek.org/2012/04/19/using-beaker-for-caching-why-you-ll-want-to-switch-to-dogpile.cache</link>
      <pubDate>Thu, 19 Apr 2012 12:01:00 EDT</pubDate>
      <category><![CDATA[Code]]></category>
      <guid isPermaLink="true">http://techspot.zzzeek.org/2012/04/19/using-beaker-for-caching-why-you-ll-want-to-switch-to-dogpile.cache</guid>
      <description>Using Beaker for Caching?  Why You'll Want to Switch to dogpile.cache</description>
      <content:encoded><![CDATA[<div class="document">
<p>Continuing on where I left off regarding Beaker in October (see <a class="reference external" href="/2011/10/01/thoughts-on-beaker/">Thoughts on Beaker</a>),
my new replacement for Beaker caching, <a class="reference external" href="https://bitbucket.org/zzzeek/dogpile.cache">dogpile.cache</a>, has had a bunch of
early releases.   While I'm still considering it &quot;alpha&quot; until I know a few people have taken it around the block,
it should be pretty much set for early testing and hopefully can be tagged as production quality in the near future.</p>
<p>The core of Beaker's caching mechanism is based on code I first wrote in 2005.   It was adapted from what was
basically my first Python program ever, a web template engine called Myghty, which in turn was based on
a Perl system called HTML::Mason.   The caching scenarios Beaker was designed for were primarily that of storing
data in files, such as DBM files.   A key assumption made at that time was that the backends would all provide
some system of returning a flag whether or not a key was present, which would precede the actual fetch of
the value from the cache.  Another assumption made was that the actual lock applied to these backends
to deal with the dogpile situation would be at its most &quot;distributed&quot; scope a file-based lock, using <tt class="docutils literal">flock()</tt>.</p>
<p>When memcached support was added to Beaker, these assumptions proved to be architectural shortcomings.
There is no &quot;check for a key&quot; function in memcached; there's only <tt class="docutils literal">get()</tt>.  Beaker's dogpile lock
calls &quot;check for a key&quot; twice.  As a result, Beaker
will in general pull a value out of memcached <strong>three times</strong>, each time resulting in an &quot;unpickle&quot; of a pickled
object.   The upshot of this is that <strong>Beaker pulls over the network and unpickles your object
three times times on every cache hit</strong>.
Users of Beaker are also well familiar with the awkward lock files Beaker insists on
generating, even though there are more appropriate ways to lock for distributed caches.</p>
<p>So for no other reason than these, dogpile.cache's entirely new and extremely simplified architecture
is an improvement of vast proportions.    The test program below illustrates the improvement in
unpickling behavior, as well as dogpile.cache's simplified API:</p>


<div class="pygments_manni"><pre><span class="k">class</span> <span class="nc">Widget</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Sample object to be cached.</span>

<span class="sd">    Counts pickles and unpickles.</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">pickles</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="n">unpickles</span> <span class="o">=</span> <span class="mi">0</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="nb">id</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="nb">id</span>

    <span class="k">def</span> <span class="nf">__getstate__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">Widget</span><span class="o">.</span><span class="n">pickles</span> <span class="o">+=</span><span class="mi">1</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__dict__</span>

    <span class="k">def</span> <span class="nf">__setstate__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">state</span><span class="p">):</span>
        <span class="n">Widget</span><span class="o">.</span><span class="n">unpickles</span> <span class="o">+=</span><span class="mi">1</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">__dict__</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">state</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">test_beaker</span><span class="p">():</span>
    <span class="kn">from</span> <span class="nn">beaker</span> <span class="kn">import</span> <span class="n">cache</span>

    <span class="n">cache_manager</span> <span class="o">=</span> <span class="n">cache</span><span class="o">.</span><span class="n">CacheManager</span><span class="p">(</span><span class="n">cache_regions</span><span class="o">=</span><span class="p">{</span>
    <span class="s">&#39;default&#39;</span> <span class="p">:{</span>
            <span class="s">&#39;type&#39;</span><span class="p">:</span><span class="s">&#39;memcached&#39;</span><span class="p">,</span>
            <span class="s">&#39;url&#39;</span><span class="p">:</span><span class="s">&#39;127.0.0.1:11211&#39;</span><span class="p">,</span>
            <span class="s">&#39;expiretime&#39;</span><span class="p">:</span><span class="mi">1</span><span class="p">,</span>
            <span class="s">&#39;lock_dir&#39;</span><span class="p">:</span><span class="s">&#39;.&#39;</span><span class="p">,</span>
            <span class="s">&#39;key_length&#39;</span><span class="p">:</span><span class="mi">250</span>
        <span class="p">}</span>
    <span class="p">})</span>

    <span class="nd">@cache_manager.region</span><span class="p">(</span><span class="s">&quot;default&quot;</span><span class="p">,</span> <span class="s">&quot;some_key&quot;</span><span class="p">)</span>
    <span class="k">def</span> <span class="nf">get_widget_beaker</span><span class="p">(</span><span class="nb">id</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">Widget</span><span class="p">(</span><span class="nb">id</span><span class="p">)</span>

    <span class="n">_run_test</span><span class="p">(</span><span class="n">get_widget_beaker</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">test_dogpile</span><span class="p">():</span>
    <span class="kn">from</span> <span class="nn">dogpile.cache</span> <span class="kn">import</span> <span class="n">make_region</span>
    <span class="kn">from</span> <span class="nn">dogpile.cache.util</span> <span class="kn">import</span> <span class="n">sha1_mangle_key</span>

    <span class="n">region</span> <span class="o">=</span> <span class="n">make_region</span><span class="p">(</span><span class="n">key_mangler</span><span class="o">=</span><span class="n">sha1_mangle_key</span><span class="p">)</span><span class="o">.</span><span class="n">configure</span><span class="p">(</span>
        <span class="s">&#39;dogpile.cache.memcached&#39;</span><span class="p">,</span>
        <span class="n">expiration_time</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
        <span class="n">arguments</span> <span class="o">=</span> <span class="p">{</span>
            <span class="s">&#39;url&#39;</span><span class="p">:[</span><span class="s">&quot;127.0.0.1:11211&quot;</span><span class="p">],</span>
        <span class="p">},</span>
    <span class="p">)</span>

    <span class="nd">@region.cache_on_arguments</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">get_widget_dogpile</span><span class="p">(</span><span class="nb">id</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">Widget</span><span class="p">(</span><span class="nb">id</span><span class="p">)</span>

    <span class="n">_run_test</span><span class="p">(</span><span class="n">get_widget_dogpile</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">_run_test</span><span class="p">(</span><span class="n">get_widget</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Store an object, retrieve from the cache.</span>

<span class="sd">    Wait two seconds, then exercise a regeneration.</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="kn">import</span> <span class="nn">time</span>

    <span class="n">Widget</span><span class="o">.</span><span class="n">pickles</span> <span class="o">=</span> <span class="n">Widget</span><span class="o">.</span><span class="n">unpickles</span> <span class="o">=</span> <span class="mi">0</span>

    <span class="c"># create and cache a widget.</span>
    <span class="c"># no unpickle necessary.</span>
    <span class="n">w1</span> <span class="o">=</span> <span class="n">get_widget</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>

    <span class="c"># get it again.  one pull from cache</span>
    <span class="c"># equals one unpickle needed.</span>
    <span class="n">w1</span> <span class="o">=</span> <span class="n">get_widget</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>

    <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>

    <span class="c"># get from cache, will pull out the</span>
    <span class="c"># object but also the fact that it&#39;s</span>
    <span class="c"># expired (costs one unpickle).</span>
    <span class="c"># newly generated object</span>
    <span class="c"># cached and returned.</span>
    <span class="n">w1</span> <span class="o">=</span> <span class="n">get_widget</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>

    <span class="k">print</span> <span class="s">&quot;Total pickles:&quot;</span><span class="p">,</span> <span class="n">Widget</span><span class="o">.</span><span class="n">pickles</span>
    <span class="k">print</span> <span class="s">&quot;Total unpickles:&quot;</span><span class="p">,</span> <span class="n">Widget</span><span class="o">.</span><span class="n">unpickles</span>

<span class="k">print</span> <span class="s">&quot;beaker&quot;</span>
<span class="n">test_beaker</span><span class="p">()</span>

<span class="k">print</span> <span class="s">&quot;dogpile&quot;</span>
<span class="n">test_dogpile</span><span class="p">()</span>
</pre></div>



<p>Running this with a clean memcached you get:</p>


<div class="pygments_manni"><pre>beaker
Total pickles: 2
Total unpickles: 6
dogpile
Total pickles: 2
Total unpickles: 2
</pre></div>



<p>Run it a second time, so that the <tt class="docutils literal">Widget</tt> is already in the cache.  Now you get <strong>ten</strong> unpickles with Beaker compared to dogpile.cache's three:</p>


<div class="pygments_manni"><pre>beaker
Total pickles: 2
Total unpickles: 10
dogpile
Total pickles: 2
Total unpickles: 3
</pre></div>



<p>The advantages of dogpile.cache go way beyond that:</p>
<ul class="simple">
<li>dogpile.cache includes distinct memcached backends for <tt class="docutils literal">pylibmc</tt>,
<tt class="docutils literal">memcache</tt> and <tt class="docutils literal">bmemcached</tt>.  These are all explicitly available
via different backend names, in contrast to Beaker's approach of deciding
for you which memcached backend it wants to use.</li>
<li>A dedicated API-space for backend-specific arguments, such as all the special
arguments <tt class="docutils literal">pylibmc</tt> offers.</li>
<li>A Redis backend is provided.</li>
<li>The system of &quot;dogpile locking&quot; is completely modular, and in the case
of memcached and Redis, a &quot;distributed lock&quot; option is provided which will
use the &quot;set key if not exists&quot; feature of those backends to provide
the dogpile lock.   A plain threaded mutex can be specified also.</li>
<li>Cache regions and function decorators are open ended.  You can
plug in your own system of generating cache keys from decorated functions,
as well as what kind of &quot;key mangling&quot; you'd like to apply to keys
going into the cache (such as encoding, hashing, etc.)</li>
<li>No lockfiles whatsoever unless you use the provided DBM backend; and
there, you tell it exactly where to put the lockfile, or tell it
to use a regular mutex instead.</li>
<li>New backends are ridiculously simple to write, and can be popped in
using regular setuptools entry points or in-application using
the <a class="reference external" href="http://dogpilecache.readthedocs.org/en/latest/usage.html#creating-backends">register_backend()</a>
function.</li>
<li>Vastly simplified scope - there's no dilution of the task at hand
with session, cookie, or encryption features.</li>
<li>Python 3 compatible in-place with no 2to3 step needed.</li>
</ul>
<p>So I'm hoping we can all soon get modernized onto dogpile.cache.</p>
<p><a class="reference external" href="http://dogpilecache.readthedocs.org/">dogpile.cache documentation</a>.</p>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Pycon 2012 : Hand Coded Applications with SQLAlchemy</title>
      <link>http://techspot.zzzeek.org/2012/03/12/pycon-2012-hand-coded-applications-with-sqlalchemy</link>
      <pubDate>Mon, 12 Mar 2012 12:01:00 EDT</pubDate>
      <category><![CDATA[SQLAlchemy]]></category>
      <category><![CDATA[Code]]></category>
      <guid isPermaLink="true">http://techspot.zzzeek.org/2012/03/12/pycon-2012-hand-coded-applications-with-sqlalchemy</guid>
      <description>Pycon 2012 : Hand Coded Applications with SQLAlchemy</description>
      <content:encoded><![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:encoded>
    </item>
    <item>
      <title>Patterns Implemented by SQLAlchemy</title>
      <link>http://techspot.zzzeek.org/2012/02/07/patterns-implemented-by-sqlalchemy</link>
      <pubDate>Tue, 07 Feb 2012 12:01:00 EST</pubDate>
      <category><![CDATA[SQLAlchemy]]></category>
      <category><![CDATA[Code]]></category>
      <guid isPermaLink="true">http://techspot.zzzeek.org/2012/02/07/patterns-implemented-by-sqlalchemy</guid>
      <description>Patterns Implemented by SQLAlchemy</description>
      <content:encoded><![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:encoded>
    </item>
  </channel>
</rss>
