<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>techspot.zzzeek.org</title>
	<atom:link href="http://techspot.zzzeek.org/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://techspot.zzzeek.org</link>
	<description>the rare comment from Mike Bayer</description>
	<pubDate>Mon, 12 Oct 2009 16:07:46 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>SQLAlchemy 0.6 ....Getting Warmer</title>
		<link>http://techspot.zzzeek.org/?p=36</link>
		<comments>http://techspot.zzzeek.org/?p=36#comments</comments>
		<pubDate>Mon, 12 Oct 2009 16:07:46 +0000</pubDate>
		<dc:creator>zzzeek</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://techspot.zzzeek.org/?p=36</guid>
		<description><![CDATA[It's super-hard to find good large blocks of time to work on SQLAlchemy at the moment...but I did manage to get most of the major "whats new?" bits up on the wiki.    I'm really close to pulling the trigger on a beta release, and we already have people running trunk.   [...]]]></description>
			<content:encoded><![CDATA[<p>It's super-hard to find good large blocks of time to work on SQLAlchemy at the moment...but I did manage to get most of the major "whats new?" bits up on the wiki.    I'm really close to pulling the trigger on a beta release, and we already have people running trunk.   There's just a certain presence of mind I like to have before releasing that hasn't been clicking on weekends.  </p>

<p>Read about the big new items and what to expect when upgrading, at <a href="http://www.sqlalchemy.org/trac/wiki/06Migration">http://www.sqlalchemy.org/trac/wiki/06Migration</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://techspot.zzzeek.org/?feed=rss2&amp;p=36</wfw:commentRss>
		</item>
		<item>
		<title>SQLAlchemy 0.5.4p1 Recommended for All Ages</title>
		<link>http://techspot.zzzeek.org/?p=35</link>
		<comments>http://techspot.zzzeek.org/?p=35#comments</comments>
		<pubDate>Mon, 18 May 2009 17:37:35 +0000</pubDate>
		<dc:creator>zzzeek</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://techspot.zzzeek.org/?p=35</guid>
		<description><![CDATA[I don't usually blog about releases, especially point releases, but this one is pretty significant in that we've repaired some very severe speed bumps that were impacting the flush() process.  Anyone working with large numbers of objects that has observed the Session to slow down as it gets bigger should download this release, as [...]]]></description>
			<content:encoded><![CDATA[<p>I don't usually blog about releases, especially point releases, but this one is pretty significant in that we've repaired some very severe speed bumps that were impacting the flush() process.  Anyone working with large numbers of objects that has observed the Session to slow down as it gets bigger should download this release, as that issue has been resolved.   Other latencies within flush() have also been flattened, and a few spreadsheet jobs that I run here which were taking 20-30 minutes now complete in about five.</p>

<p>It's still not nearly as fast as running a single huge executemany() to insert lots of rows, but if your experience with this release is like mine you should see much faster runs for large data update operations.  As usual there's dozens of other fixes and enhancements too.</p>

<p>SQLAlchemy 0.5.4p1's download page is at:</p>

<p><a href="http://www.sqlalchemy.org/download.html">http://www.sqlalchemy.org/download.html</a></p>

<p>or, just use <code>easy_install</code>.</p>

<p>Work on the 0.6 series continues, as this release is focused on expanding the world of compatibility for SQLAlchemy, including compatibility with Python 3K, Jython, and many more DBAPI implementations.   It also refactors DDL generation to work within the same compiler framework as that of non-DDL expressions, so you can easily create and execute <code>CreateTable</code> kinds of objects.  Database reflection has been greatly enhanced with a new <code>Inspector</code> API too.</p>
]]></content:encoded>
			<wfw:commentRss>http://techspot.zzzeek.org/?feed=rss2&amp;p=35</wfw:commentRss>
		</item>
		<item>
		<title>Oracle Buys.....MySQL ??!</title>
		<link>http://techspot.zzzeek.org/?p=34</link>
		<comments>http://techspot.zzzeek.org/?p=34#comments</comments>
		<pubDate>Mon, 20 Apr 2009 15:21:53 +0000</pubDate>
		<dc:creator>zzzeek</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://techspot.zzzeek.org/?p=34</guid>
		<description><![CDATA[Let's meditate on this for a moment.

Oracle will own MySQL.

time to take the postgres plunge ?  (all those who haven't as of yet).
]]></description>
			<content:encoded><![CDATA[<p>Let's meditate on this for a moment.</p>

<p><em>Oracle will own MySQL.</em></p>

<p>time to take the postgres plunge ?  (all those who haven't as of yet).</p>
]]></content:encoded>
			<wfw:commentRss>http://techspot.zzzeek.org/?feed=rss2&amp;p=34</wfw:commentRss>
		</item>
		<item>
		<title>SQLAlchemy - Breaking the 80% Barrier Since Day One</title>
		<link>http://techspot.zzzeek.org/?p=33</link>
		<comments>http://techspot.zzzeek.org/?p=33#comments</comments>
		<pubDate>Sat, 10 Jan 2009 21:56:32 +0000</pubDate>
		<dc:creator>zzzeek</dc:creator>
		
		<category><![CDATA[SQLAlchemy]]></category>

		<guid isPermaLink="false">http://techspot.zzzeek.org/?p=33</guid>
		<description><![CDATA[As the 0.5 release of SQLAlchemy has now become available, here's a little retrospective on the "relational" nature of SQLAlchemy.   SQLAlchemy's equal treatment of any relation and its deep transformational abilities of such are the core value that makes us highly unique within the database access/ORM field.  It's the key to our [...]]]></description>
			<content:encoded><![CDATA[<p>As the <a href="http://www.sqlalchemy.org/news.html#item_1">0.5 release of SQLAlchemy</a> has now become available, here's a little retrospective on the "relational" nature of SQLAlchemy.   SQLAlchemy's equal treatment of any <a href="http://en.wikipedia.org/wiki/Relational_model">relation</a> and its deep transformational abilities of such are the core value that makes us highly unique within the database access/ORM field.  It's the key to our <a href="http://spyced.blogspot.com/2006/05/sqlalchemy-world-domination-tour.html">80% Busting</a> power which allow an application architected around SQLAlchemy to smoothly co-evolve with an ever-more complex set of queries and schemas.</p>

<p>To illustrate this, we'll walk through an 0.5 feature that draws upon the three years of effort that's gone into this capability.</p>

<p>As is typical, we start in an entirely boring way:</p>
<pre class="wp_syntax"><code><span style="color: #0908ce;font-weight:bold;">from</span> sqlalchemy <span style="color: #0908ce;font-weight:bold;">import</span> Column, Integer, Unicode, create_engine
<span style="color: #0908ce;font-weight:bold;">from</span> sqlalchemy.<span style="color: black;">orm</span> <span style="color: #0908ce;font-weight:bold;">import</span> sessionmaker
<span style="color: #0908ce;font-weight:bold;">from</span> sqlalchemy.<span style="color: black;">ext</span>.<span style="color: black;">declarative</span> <span style="color: #0908ce;font-weight:bold;">import</span> declarative_base
&nbsp;
Base = declarative_base<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #0908ce;font-weight:bold;">class</span> Foo<span style="color: black;">&#40;</span>Base<span style="color: black;">&#41;</span>:
    __tablename__ = <span style="color: #E04500;">'foo'</span>
    <span style="color: #6f0005;">id</span> = Column<span style="color: black;">&#40;</span>Integer, primary_key=<span style="color: #6f0005;">True</span><span style="color: black;">&#41;</span>
    data = Column<span style="color: black;">&#40;</span>Unicode<span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #0908ce;font-weight:bold;">def</span> <span style="color: #0000cd;">__repr__</span><span style="color: black;">&#40;</span><span style="color: #6f0005;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #0908ce;font-weight:bold;">return</span> <span style="color: #E04500;">&quot;Foo(%r)&quot;</span> % <span style="color: #6f0005;">self</span>.<span style="color: black;">data</span>
&nbsp;
engine = create_engine<span style="color: black;">&#40;</span><span style="color: #E04500;">'sqlite:///:memory:'</span>, echo=<span style="color: #6f0005;">True</span><span style="color: black;">&#41;</span>
Base.<span style="color: black;">metadata</span>.<span style="color: black;">create_all</span><span style="color: black;">&#40;</span>engine<span style="color: black;">&#41;</span>
&nbsp;
session = sessionmaker<span style="color: black;">&#40;</span>engine<span style="color: black;">&#41;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></pre>

<p>To those unfamiliar with SQLA, the above example is specific to the ORM portion of SQLAlchemy (as opposed to the SQL expression language, an independent library upon which the ORM builds).  It consists of the requisite imports, a <code>declarative_base()</code> class which offers us an easy platform with which to construct database-enabled classes, a <code>Foo</code> mapped class with some pretty generic columns, and the specification of a datasource, CREATE TABLE statements as needed, and an ORM session to pull it together.  Everything above is detailed in the <a href="http://www.sqlalchemy.org/docs/05/ormtutorial.html">Object Relational Tutorial</a> (now with <a href="http://sphinx.pocoo.org">Sphinx!</a>).</p>

<p>The data we'll start with is five objects with predictable data values:</p>
<pre class="wp_syntax"><code>session.<span style="color: black;">add_all</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>
    Foo<span style="color: black;">&#40;</span>data=u<span style="color: #E04500;">'f1'</span><span style="color: black;">&#41;</span>,
    Foo<span style="color: black;">&#40;</span>data=u<span style="color: #E04500;">'f2'</span><span style="color: black;">&#41;</span>,
    Foo<span style="color: black;">&#40;</span>data=u<span style="color: #E04500;">'f3'</span><span style="color: black;">&#41;</span>,
    Foo<span style="color: black;">&#40;</span>data=u<span style="color: #E04500;">'f4'</span><span style="color: black;">&#41;</span>,
    Foo<span style="color: black;">&#40;</span>data=u<span style="color: #E04500;">'f5'</span><span style="color: black;">&#41;</span>,
<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
session.<span style="color: black;">commit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></pre>

<p>In 0.5, we can now query individual columns at the ORM level.  So starting with a query like this:</p>
<pre class="wp_syntax"><code>query = session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>Foo.<span style="color: #6f0005;">id</span>, Foo.<span style="color: black;">data</span><span style="color: black;">&#41;</span></code></pre>

<p>We can receive the results of this query using <code>all()</code> (we'll move to doctest format where the output can be viewed):</p>
<pre class="wp_syntax"><code>&gt;&gt;&gt; <span style="color: #0908ce;font-weight:bold;">print</span> query.<span style="color: black;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
SELECT foo.<span style="color: #6f0005;">id</span> AS foo_id, foo.<span style="color: black;">data</span> AS foo_data 
FROM foo
<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #E04500;">1</span>, u<span style="color: #E04500;">'f1'</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">2</span>, u<span style="color: #E04500;">'f2'</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">3</span>, u<span style="color: #E04500;">'f3'</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">4</span>, u<span style="color: #E04500;">'f4'</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">5</span>, u<span style="color: #E04500;">'f5'</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span></code></pre>

<p>The individual column query feature is nice - but still very boring !  It's nothing you can't do with any other tool, and SQLA actually lagged behind a bit in offering this capability in a straightforward way at the ORM level, which is partially because it was always possible with the SQL expression language part of SQLAlchemy, and partially because our <code>Query</code> has a broad usage contract that took a while to adapt to this model.  Water under the bridge....</p>

<p>Things remain patently boring as we decide to limit the results to just the first three rows:</p>
<pre class="wp_syntax"><code>&gt;&gt;&gt; <span style="color: #0908ce;font-weight:bold;">print</span> query.<span style="color: black;">limit</span><span style="color: black;">&#40;</span><span style="color: #E04500;">3</span><span style="color: black;">&#41;</span>.<span style="color: black;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
SELECT foo.<span style="color: #6f0005;">id</span> AS foo_id, foo.<span style="color: black;">data</span> AS foo_data 
FROM foo 
LIMIT <span style="color: #E04500;">3</span> OFFSET <span style="color: #E04500;">0</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #E04500;">1</span>, u<span style="color: #E04500;">'f1'</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">2</span>, u<span style="color: #E04500;">'f2'</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">3</span>, u<span style="color: #E04500;">'f3'</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span></code></pre>

<p>Did I see something flicker in the corner ?   Not really, we're just adding a descending order by so that we get the <em>last</em> three rows instead.  Yaawwwnnnnn:</p>
<pre class="wp_syntax"><code>&gt;&gt;&gt; <span style="color: #0908ce;font-weight:bold;">print</span> query.<span style="color: black;">order_by</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">data</span>.<span style="color: black;">desc</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">limit</span><span style="color: black;">&#40;</span><span style="color: #E04500;">3</span><span style="color: black;">&#41;</span>.<span style="color: black;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
SELECT foo.<span style="color: #6f0005;">id</span> AS foo_id, foo.<span style="color: black;">data</span> AS foo_data 
FROM foo ORDER BY foo.<span style="color: black;">data</span> DESC 
LIMIT <span style="color: #E04500;">3</span> OFFSET <span style="color: #E04500;">0</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #E04500;">5</span>, u<span style="color: #E04500;">'f5'</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">4</span>, u<span style="color: #E04500;">'f4'</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">3</span>, u<span style="color: #E04500;">'f3'</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span></code></pre>

<p>Barely staying awake, we'd like to sort the above rows in name ascending order so that we get <code>['f3', 'f4', 'f5']</code> instead.  To do this, it's, errr, umm.......</p>

<h1>Eighty Percent Time !!!</h1>

<p>What just happened ?  Proceeding through an entirely boring series of modifications to our query, we've suddenly hit something that is not entirely obvious.  This is where any afternoon-coded SQL tool falls off, because to limit by the last three rows, and then order the limited results in reverse, requires a subquery.  Not just a scalar subquery like <code>WHERE x=(SELECT y FROM table)</code> either - a subquery that acts the same way as we've been treating our table - a "selectable" which delivers rows that correspond to our <code>Foo</code> class, to which we can then apply an ascending ORDER BY.</p>

<p>Let's be fair.  You could get the results you want using a WHERE subquery, such as in conjunction with <code>IN</code>.  <code>"SELECT * FROM foo WHERE id IN (SELECT id FROM foo ORDER BY data DESC LIMIT 3) ORDER BY data"</code> would do it.  There's other ways too like <code>EXISTS</code>, or maybe issuing a <code>JOIN</code> to the subquery (another tall order for some tools).  However, let me respectfully say that this is lame.  You're rearranging your SQL and introducing potentially reduced query optimization because your tool won't let you do the most obvious thing (or more importantly, <em>exactly what you want to do</em>).  This is a typical 80% boundary.  You pull this one last Jenga stick out and the whole thing collapses, as your tool no longer supports the natural progression of expression construction that direct SQL offers you.  You need to drop into raw SQL or you need to restructure your whole query to work around the tool's limitations.  </p>

<p>Before we continue, here's a pop quiz.   What would be the expected behavior of the following:</p>
<pre class="wp_syntax"><code>query = session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>Foo.<span style="color: #6f0005;">id</span>, Foo.<span style="color: black;">data</span><span style="color: black;">&#41;</span>
query = query.<span style="color: black;">order_by</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">data</span>.<span style="color: black;">desc</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">limit</span><span style="color: black;">&#40;</span><span style="color: #E04500;">3</span><span style="color: black;">&#41;</span>
query = query.<span style="color: black;">order_by</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">data</span><span style="color: black;">&#41;</span>
<span style="color: #0908ce;font-weight:bold;">print</span> query.<span style="color: black;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></pre>

<p>Where above, we order by <code>data</code> descending, then <code>LIMIT 3</code>, then order by <code>data</code> ascending.  Does it:</p>

<ul>
<li>a. Issue <code>ORDER BY data DESC, data</code> and then issue the <code>LIMIT</code> ?</li>
<li>b. Issue <code>ORDER BY data DESC LIMIT 3</code>, and then <code>ORDER BY</code> on a subquery of the preceding statement ?</li>
</ul>

<p>As it turns out, the answer to this question is subjective.  Depending on the perspective one comes from, we've observed based on talking to our community that some expect "a" and some expect "b".   So in refusing to guess, here's what it does:</p>
<pre class="wp_syntax"><code>&gt;&gt;&gt; query = session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>Foo.<span style="color: #6f0005;">id</span>, Foo.<span style="color: black;">data</span><span style="color: black;">&#41;</span>
&gt;&gt;&gt; query = query.<span style="color: black;">order_by</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">data</span>.<span style="color: black;">desc</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">limit</span><span style="color: black;">&#40;</span><span style="color: #E04500;">3</span><span style="color: black;">&#41;</span>
&gt;&gt;&gt; query = query.<span style="color: black;">order_by</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">data</span><span style="color: black;">&#41;</span>
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
    ...
<span style="color: black;">sqlalchemy</span>.<span style="color: black;">exc</span>.<span style="color: black;">InvalidRequestError</span>: Query.<span style="color: black;">order_by</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> being called on a Query which already has LIMIT <span style="color: #0908ce;font-weight:bold;">or</span> OFFSET applied. <span style="color: black;">To</span> modify the row-limited results of a Query, call from_self<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> first.  <span style="color: black;">Otherwise</span>, call order_by<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> before limit<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #0908ce;font-weight:bold;">or</span> offset<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> are applied.</code></pre>

<p>We went with "please tell us which answer you'd like".   Specifying <code>from_self()</code> means "yes, we really want to wrap the whole thing in a subquery before continuing":</p>
<pre class="wp_syntax"><code>&gt;&gt;&gt; query = query.<span style="color: black;">from_self</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">order_by</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">data</span><span style="color: black;">&#41;</span>
&gt;&gt;&gt; <span style="color: #0908ce;font-weight:bold;">print</span> query.<span style="color: black;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
SELECT anon_1.<span style="color: black;">foo_id</span> AS anon_1_foo_id, anon_1.<span style="color: black;">foo_data</span> AS anon_1_foo_data 
FROM <span style="color: black;">&#40;</span>SELECT foo.<span style="color: #6f0005;">id</span> AS foo_id, foo.<span style="color: black;">data</span> AS foo_data 
FROM foo ORDER BY foo.<span style="color: black;">data</span> DESC 
 LIMIT <span style="color: #E04500;">3</span> OFFSET <span style="color: #E04500;">0</span><span style="color: black;">&#41;</span> AS anon_1 ORDER BY anon_1.<span style="color: black;">foo_data</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #E04500;">3</span>, u<span style="color: #E04500;">'f3'</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">4</span>, u<span style="color: #E04500;">'f4'</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">5</span>, u<span style="color: #E04500;">'f5'</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span></code></pre>

<p>The mechanism by which SQLAlchemy uses to wrap tables in subqueries but consistently target the columns back to our mapped columns and entities is called <strong>Column Correspondence</strong> - this is something I described in detail in <a href="http://techspot.zzzeek.org/?p=19">this blog post</a>.  I'm not familiar with any formalized system that describes column correspondence from a relational standpoint, but if someone out there is, I'd appreciate the education.  I'm not at all a formalist and I've built this whole thing in my garage.</p>

<p>We still haven't hit the "retrospective" and/or "day one" part of the story yet.  <code>from_self()</code> is just one of many ways to get at SQLAlchemy's "relational" guts, the big "under the hood" feature that's taken (and continues to take) a long time to get right.  In the old days these guts were exposed in the ORM in extremely limited ways.  As we've progressed, we're able to allow more generalized access to it, such as via <code>from_self()</code>.  Let's illustrate another <code>from_self()</code> example that can link back to one of SQLA's original "80% busters".</p>

<p>Like all SQLAlchemy examples, we add a second class <code>Bar</code>, relate it to <code>Foo</code>, and add some more data:</p>
<pre class="wp_syntax"><code><span style="color: #0908ce;font-weight:bold;">from</span> sqlalchemy <span style="color: #0908ce;font-weight:bold;">import</span> ForeignKey
<span style="color: #0908ce;font-weight:bold;">from</span> sqlalchemy.<span style="color: black;">orm</span> <span style="color: #0908ce;font-weight:bold;">import</span> relation, backref
&nbsp;
<span style="color: #0908ce;font-weight:bold;">class</span> Bar<span style="color: black;">&#40;</span>Base<span style="color: black;">&#41;</span>:
    __tablename__ = <span style="color: #E04500;">'bar'</span>
    <span style="color: #6f0005;">id</span> = Column<span style="color: black;">&#40;</span>Integer, primary_key=<span style="color: #6f0005;">True</span><span style="color: black;">&#41;</span>
    data = Column<span style="color: black;">&#40;</span>Unicode<span style="color: black;">&#41;</span>
    foo_id = Column<span style="color: black;">&#40;</span>Integer, ForeignKey<span style="color: black;">&#40;</span><span style="color: #E04500;">'foo.id'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    foo = relation<span style="color: black;">&#40;</span>Foo, backref=backref<span style="color: black;">&#40;</span><span style="color: #E04500;">'bars'</span>, collection_class=<span style="color: #6f0005;">set</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #0908ce;font-weight:bold;">def</span> <span style="color: #0000cd;">__repr__</span><span style="color: black;">&#40;</span><span style="color: #6f0005;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #0908ce;font-weight:bold;">return</span> <span style="color: #E04500;">&quot;Bar(%r)&quot;</span> % <span style="color: #6f0005;">self</span>.<span style="color: black;">data</span>
&nbsp;
Base.<span style="color: black;">metadata</span>.<span style="color: black;">create_all</span><span style="color: black;">&#40;</span>engine<span style="color: black;">&#41;</span>
&nbsp;
f3 = session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>Foo<span style="color: black;">&#41;</span>.<span style="color: #6f0005;">filter</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">data</span>==u<span style="color: #E04500;">'f3'</span><span style="color: black;">&#41;</span>.<span style="color: black;">one</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
f5 = session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>Foo<span style="color: black;">&#41;</span>.<span style="color: #6f0005;">filter</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">data</span>==u<span style="color: #E04500;">'f5'</span><span style="color: black;">&#41;</span>.<span style="color: black;">one</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
session.<span style="color: black;">add_all</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>
    Bar<span style="color: black;">&#40;</span>data=u<span style="color: #E04500;">'b1'</span>, foo=f3<span style="color: black;">&#41;</span>,
    Bar<span style="color: black;">&#40;</span>data=u<span style="color: #E04500;">'b2'</span>, foo=f5<span style="color: black;">&#41;</span>,
    Bar<span style="color: black;">&#40;</span>data=u<span style="color: #E04500;">'b3'</span>, foo=f5<span style="color: black;">&#41;</span>,
    Bar<span style="color: black;">&#40;</span>data=u<span style="color: #E04500;">'b4'</span>, foo=f5<span style="color: black;">&#41;</span>,
    <span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
session.<span style="color: black;">commit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></pre>

<p>We've added four <code>Bar</code> objects, each of which references a <code>Foo</code> object via many-to-one.  The corresponding <code>Foo</code> object references each <code>Bar</code> via a one-to-many collection.   For background, this is also <a href="http://www.sqlalchemy.org/docs/05/ormtutorial.html">ORM Tutorial</a> stuff.</p>

<p>Let's now do the obvious thing of selecting all the data at once.   Just for fun we'll do the query like this (yes, you can mix columns and full entities freely):</p>
<pre class="wp_syntax"><code>&gt;&gt;&gt; query = session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>Foo.<span style="color: #6f0005;">id</span>, Foo.<span style="color: black;">data</span>, Bar<span style="color: black;">&#41;</span>.<span style="color: black;">outerjoin</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">bars</span><span style="color: black;">&#41;</span>
&gt;&gt;&gt; <span style="color: #0908ce;font-weight:bold;">print</span> query.<span style="color: black;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
SELECT foo.<span style="color: #6f0005;">id</span> AS foo_id, foo.<span style="color: black;">data</span> AS foo_data, bar.<span style="color: #6f0005;">id</span> AS bar_id, 
  bar.<span style="color: black;">data</span> AS bar_data, bar.<span style="color: black;">foo_id</span> AS bar_foo_id 
FROM foo LEFT OUTER JOIN bar ON foo.<span style="color: #6f0005;">id</span> = bar.<span style="color: black;">foo_id</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #E04500;">1</span>, u<span style="color: #E04500;">'f1'</span>, <span style="color: #6f0005;">None</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">2</span>, u<span style="color: #E04500;">'f2'</span>, <span style="color: #6f0005;">None</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">3</span>, u<span style="color: #E04500;">'f3'</span>, Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b1'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">4</span>, u<span style="color: #E04500;">'f4'</span>, <span style="color: #6f0005;">None</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">5</span>, u<span style="color: #E04500;">'f5'</span>, Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b2'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">5</span>, u<span style="color: #E04500;">'f5'</span>, Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b3'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">5</span>, u<span style="color: #E04500;">'f5'</span>, Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b4'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span></code></pre>

<p>Above we're using <code>outerjoin(Foo.bars)</code> to say "outer join from the <code>foo</code> table to the <code>bar</code> table".  <code>Foo.bars</code> was configured via the <code>backref</code> for <code>Bar.foo</code>.   We can see we get <code>f5</code> back three times since three <code>Bar</code> rows match.</p>

<p>So what if we'd like to select all the <code>Foo</code> and <code>Bar</code> rows, but like before we want to get the last three <code>Foo</code>s ?  We can't do the same thing we did earlier - a straight LIMIT will be limited by the total number of rows, including the multiple <code>f5</code> rows:</p>
<pre class="wp_syntax"><code>&gt;&gt;&gt; <span style="color: #0908ce;font-weight:bold;">print</span> query.<span style="color: black;">order_by</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">data</span>.<span style="color: black;">desc</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">limit</span><span style="color: black;">&#40;</span><span style="color: #E04500;">3</span><span style="color: black;">&#41;</span>.<span style="color: black;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
SELECT foo.<span style="color: #6f0005;">id</span> AS foo_id, foo.<span style="color: black;">data</span> AS foo_data, bar.<span style="color: #6f0005;">id</span> AS bar_id, 
  bar.<span style="color: black;">data</span> AS bar_data, bar.<span style="color: black;">foo_id</span> AS bar_foo_id 
FROM foo LEFT OUTER JOIN bar ON foo.<span style="color: #6f0005;">id</span> = bar.<span style="color: black;">foo_id</span> ORDER BY foo.<span style="color: black;">data</span> DESC 
 LIMIT <span style="color: #E04500;">3</span> OFFSET <span style="color: #E04500;">0</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #E04500;">5</span>, u<span style="color: #E04500;">'f5'</span>, Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b2'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">5</span>, u<span style="color: #E04500;">'f5'</span>, Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b3'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">5</span>, u<span style="color: #E04500;">'f5'</span>, Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b4'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span></code></pre>

<p>Once again, to get the right data, we can do some less straightforward <code>IN</code> or <code>EXISTS</code> methodology, or we can do the most direct thing and join <code>bar</code> to the subquery of <code>foo</code> which we'd like.  <code>Query</code> allows us to build up the statement exactly as we'd do it when thinking in SQL:</p>
<pre class="wp_syntax"><code>&gt;&gt;&gt; query = session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>Foo<span style="color: black;">&#41;</span>.<span style="color: black;">order_by</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">data</span>.<span style="color: black;">desc</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">limit</span><span style="color: black;">&#40;</span><span style="color: #E04500;">3</span><span style="color: black;">&#41;</span></code></pre>

<p><code>from_self()</code> will create the subuquery for us, but we also want to change the columns we're selecting from, since we'll be adding <code>Bar</code> via an outer join.  For this purpose <code>from_self()</code> takes the same parameters as <code>session.query()</code>:</p>
<pre class="wp_syntax"><code>&gt;&gt;&gt; <span style="color: #0908ce;font-weight:bold;">print</span> query.<span style="color: black;">from_self</span><span style="color: black;">&#40;</span>Foo.<span style="color: #6f0005;">id</span>, Foo.<span style="color: black;">data</span>, Bar<span style="color: black;">&#41;</span>.<span style="color: black;">outerjoin</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">bars</span><span style="color: black;">&#41;</span>.\
...     <span style="color: black;">order_by</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">data</span><span style="color: black;">&#41;</span>.<span style="color: black;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
SELECT anon_1.<span style="color: black;">foo_id</span> AS anon_1_foo_id, anon_1.<span style="color: black;">foo_data</span> AS anon_1_foo_data, 
  bar.<span style="color: #6f0005;">id</span> AS bar_id, bar.<span style="color: black;">data</span> AS bar_data, bar.<span style="color: black;">foo_id</span> AS bar_foo_id 
FROM <span style="color: black;">&#40;</span>SELECT foo.<span style="color: #6f0005;">id</span> AS foo_id, foo.<span style="color: black;">data</span> AS foo_data 
FROM foo ORDER BY foo.<span style="color: black;">data</span> DESC 
LIMIT <span style="color: #E04500;">3</span> OFFSET <span style="color: #E04500;">0</span><span style="color: black;">&#41;</span> AS anon_1 
LEFT OUTER JOIN bar ON anon_1.<span style="color: black;">foo_id</span> = bar.<span style="color: black;">foo_id</span> 
ORDER BY anon_1.<span style="color: black;">foo_data</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#40;</span><span style="color: #E04500;">3</span>, u<span style="color: #E04500;">'f3'</span>, Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b1'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">4</span>, u<span style="color: #E04500;">'f4'</span>, <span style="color: #6f0005;">None</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">5</span>, u<span style="color: #E04500;">'f5'</span>, Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b2'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">5</span>, u<span style="color: #E04500;">'f5'</span>, Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b3'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>, <span style="color: black;">&#40;</span><span style="color: #E04500;">5</span>, u<span style="color: #E04500;">'f5'</span>, Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b4'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span></code></pre>

<p>Above, we can see that not only does the subquery created by <code>from_self()</code> target the result columns to our <code>Foo</code> entity, it also <em>adapts the join criterion</em> so that everything just works.  </p>

<p>Those who have worked with eager loading might recognize the above query - it is in fact the same kind of query that's been available since 0.1, that of "eager loading" a set of rows with a LEFT OUTER JOIN, but intelligently wrapping the primary query in a subquery so that LIMIT/OFFSET remains effective.  The basic idea like this:</p>
<pre class="wp_syntax"><code>&gt;&gt;&gt; <span style="color: #0908ce;font-weight:bold;">from</span> sqlalchemy.<span style="color: black;">orm</span> <span style="color: #0908ce;font-weight:bold;">import</span> eagerload
&gt;&gt;&gt; <span style="color: #0908ce;font-weight:bold;">for</span> f <span style="color: #0908ce;font-weight:bold;">in</span> session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>Foo<span style="color: black;">&#41;</span>.<span style="color: black;">options</span><span style="color: black;">&#40;</span>eagerload<span style="color: black;">&#40;</span>Foo.<span style="color: black;">bars</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.\
...             <span style="color: black;">order_by</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">data</span>.<span style="color: black;">desc</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">limit</span><span style="color: black;">&#40;</span><span style="color: #E04500;">3</span><span style="color: black;">&#41;</span>:
...     <span style="color: #0908ce;font-weight:bold;">print</span> f, <span style="color: black;">&#91;</span>b <span style="color: #0908ce;font-weight:bold;">for</span> b <span style="color: #0908ce;font-weight:bold;">in</span> f.<span style="color: black;">bars</span><span style="color: black;">&#93;</span>
... 
<span style="color: black;">SELECT</span> anon_1.<span style="color: black;">foo_id</span> AS anon_1_foo_id, anon_1.<span style="color: black;">foo_data</span> AS anon_1_foo_data, 
  bar_1.<span style="color: #6f0005;">id</span> AS bar_1_id, bar_1.<span style="color: black;">data</span> AS bar_1_data, 
  bar_1.<span style="color: black;">foo_id</span> AS bar_1_foo_id 
FROM <span style="color: black;">&#40;</span>SELECT foo.<span style="color: #6f0005;">id</span> AS foo_id, foo.<span style="color: black;">data</span> AS foo_data 
FROM foo ORDER BY foo.<span style="color: black;">data</span> DESC 
LIMIT <span style="color: #E04500;">3</span> OFFSET <span style="color: #E04500;">0</span><span style="color: black;">&#41;</span> AS anon_1 
LEFT OUTER JOIN bar AS bar_1 ON anon_1.<span style="color: black;">foo_id</span> = bar_1.<span style="color: black;">foo_id</span> 
 ORDER BY anon_1.<span style="color: black;">foo_data</span> DESC
<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
Foo<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'f5'</span><span style="color: black;">&#41;</span> <span style="color: black;">&#91;</span>Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b2'</span><span style="color: black;">&#41;</span>, Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b3'</span><span style="color: black;">&#41;</span>, Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b4'</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
Foo<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'f4'</span><span style="color: black;">&#41;</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
Foo<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'f3'</span><span style="color: black;">&#41;</span> <span style="color: black;">&#91;</span>Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b1'</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span></code></pre>

<p>Where above, we just select the <code>Foo</code> objects, and the <code>Bar</code> rows are delivered to collections attached to each <code>Foo</code> object.  The fact that we've applied <code>limit(3)</code> indicates that the selection of <code>Foo</code> rows should take place within a subquery, to which the <code>Bar</code> rows are left outer joined.  We didn't render the query quite as cleanly in 0.1 but by the 0.4 series we had gotten it to this point.</p>

<p>Finally, we can adapt our eager loaded query above to look <em>just</em> like the "last three rows of foo, outer joined to bar, ordered by 'data'" query by combining the <code>eagerload()</code> with <code>from_self()</code>:</p>
<pre class="wp_syntax"><code>&gt;&gt;&gt; <span style="color: #0908ce;font-weight:bold;">for</span> f <span style="color: #0908ce;font-weight:bold;">in</span> session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>Foo<span style="color: black;">&#41;</span>.<span style="color: black;">order_by</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">data</span>.<span style="color: black;">desc</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.\
...             <span style="color: black;">limit</span><span style="color: black;">&#40;</span><span style="color: #E04500;">3</span><span style="color: black;">&#41;</span>.<span style="color: black;">from_self</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">options</span><span style="color: black;">&#40;</span>eagerload<span style="color: black;">&#40;</span>Foo.<span style="color: black;">bars</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.\
...             <span style="color: black;">order_by</span><span style="color: black;">&#40;</span>Foo.<span style="color: black;">data</span><span style="color: black;">&#41;</span>:
...     <span style="color: #0908ce;font-weight:bold;">print</span> f, <span style="color: black;">&#91;</span>b <span style="color: #0908ce;font-weight:bold;">for</span> b <span style="color: #0908ce;font-weight:bold;">in</span> f.<span style="color: black;">bars</span><span style="color: black;">&#93;</span>
... 
<span style="color: black;">SELECT</span> anon_1.<span style="color: black;">foo_id</span> AS anon_1_foo_id, anon_1.<span style="color: black;">foo_data</span> AS anon_1_foo_data, 
 bar_1.<span style="color: #6f0005;">id</span> AS bar_1_id, bar_1.<span style="color: black;">data</span> AS bar_1_data, 
 bar_1.<span style="color: black;">foo_id</span> AS bar_1_foo_id 
FROM <span style="color: black;">&#40;</span>SELECT foo.<span style="color: #6f0005;">id</span> AS foo_id, foo.<span style="color: black;">data</span> AS foo_data 
FROM foo ORDER BY foo.<span style="color: black;">data</span> DESC 
LIMIT <span style="color: #E04500;">3</span> OFFSET <span style="color: #E04500;">0</span><span style="color: black;">&#41;</span> AS anon_1 
LEFT OUTER JOIN bar AS bar_1 ON anon_1.<span style="color: black;">foo_id</span> = bar_1.<span style="color: black;">foo_id</span> 
ORDER BY anon_1.<span style="color: black;">foo_data</span>
<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
Foo<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'f3'</span><span style="color: black;">&#41;</span> <span style="color: black;">&#91;</span>Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b1'</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
Foo<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'f4'</span><span style="color: black;">&#41;</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
Foo<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'f5'</span><span style="color: black;">&#41;</span> <span style="color: black;">&#91;</span>Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b2'</span><span style="color: black;">&#41;</span>, Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b3'</span><span style="color: black;">&#41;</span>, Bar<span style="color: black;">&#40;</span>u<span style="color: #E04500;">'b4'</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span></code></pre>

<p>I'm super excited about the 0.5 release (not to mention 0.6 for which we have a lot planned) since it represents the coming together of the original vision of offering the full relational model, years of feedback from real users with lots of production experience, and an ever more solid maturity to the internals which at this point have probably had about three full turnovers in construction.  </p>
]]></content:encoded>
			<wfw:commentRss>http://techspot.zzzeek.org/?feed=rss2&amp;p=33</wfw:commentRss>
		</item>
		<item>
		<title>Tags with SQLAlchemy</title>
		<link>http://techspot.zzzeek.org/?p=32</link>
		<comments>http://techspot.zzzeek.org/?p=32#comments</comments>
		<pubDate>Fri, 10 Oct 2008 15:46:28 +0000</pubDate>
		<dc:creator>zzzeek</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://techspot.zzzeek.org/?p=32</guid>
		<description><![CDATA[Wayne Witzel gives us a very nice tutorial on how to implement simple tagging with SQLAlchemy.   It's a totally straightforward example with nice usage of 0.5 Query paradigms as well as some SQL expression language integration (which looks familiar from the ML the other day...).
]]></description>
			<content:encoded><![CDATA[<p>Wayne Witzel gives us a very nice <a href="http://pieceofpy.com/index.php/2008/10/09/tags-with-sqlalchemy/">tutorial</a> on how to implement simple tagging with SQLAlchemy.   It's a totally straightforward example with nice usage of 0.5 Query paradigms as well as some SQL expression language integration (which looks familiar from the ML the other day...).</p>
]]></content:encoded>
			<wfw:commentRss>http://techspot.zzzeek.org/?feed=rss2&amp;p=32</wfw:commentRss>
		</item>
		<item>
		<title>Timing All Queries</title>
		<link>http://techspot.zzzeek.org/?p=31</link>
		<comments>http://techspot.zzzeek.org/?p=31#comments</comments>
		<pubDate>Tue, 16 Sep 2008 20:07:06 +0000</pubDate>
		<dc:creator>zzzeek</dc:creator>
		
		<category><![CDATA[SQLAlchemy]]></category>

		<guid isPermaLink="false">http://techspot.zzzeek.org/?p=31</guid>
		<description><![CDATA[A few people have been asking about this one as of late, it's quite easy to do with a ConnectionProxy.  Here's a quick recipe (yes, this is 0.5):
from sqlalchemy.interfaces import ConnectionProxy
import time
import logging
&#160;
logging.basicConfig&#40;&#41;
logger = logging.getLogger&#40;&#34;myapp.sqltime&#34;&#41;
logger.setLevel&#40;logging.DEBUG&#41;
&#160;
class TimerProxy&#40;ConnectionProxy&#41;:
    def cursor_execute&#40;self, execute, cursor, statement, parameters, context, executemany&#41;:
        [...]]]></description>
			<content:encoded><![CDATA[<p>A few people have been asking about this one as of late, it's quite easy to do with a <code>ConnectionProxy</code>.  Here's a quick recipe (yes, this is 0.5):</p>
<pre class="wp_syntax"><code><span style="color: #0908ce;font-weight:bold;">from</span> sqlalchemy.<span style="color: black;">interfaces</span> <span style="color: #0908ce;font-weight:bold;">import</span> ConnectionProxy
<span style="color: #0908ce;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
<span style="color: #0908ce;font-weight:bold;">import</span> <span style="color: #dc143c;">logging</span>
&nbsp;
<span style="color: #dc143c;">logging</span>.<span style="color: black;">basicConfig</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
logger = <span style="color: #dc143c;">logging</span>.<span style="color: black;">getLogger</span><span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;myapp.sqltime&quot;</span><span style="color: black;">&#41;</span>
logger.<span style="color: black;">setLevel</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">logging</span>.<span style="color: black;">DEBUG</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #0908ce;font-weight:bold;">class</span> TimerProxy<span style="color: black;">&#40;</span>ConnectionProxy<span style="color: black;">&#41;</span>:
    <span style="color: #0908ce;font-weight:bold;">def</span> cursor_execute<span style="color: black;">&#40;</span><span style="color: #6f0005;">self</span>, execute, cursor, statement, parameters, context, executemany<span style="color: black;">&#41;</span>:
        now = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #0908ce;font-weight:bold;">try</span>:
            <span style="color: #0908ce;font-weight:bold;">return</span> execute<span style="color: black;">&#40;</span>cursor, statement, parameters, context<span style="color: black;">&#41;</span>
        <span style="color: #0908ce;font-weight:bold;">finally</span>:
            total = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - now
            logger.<span style="color: black;">debug</span><span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;Query: %s&quot;</span> % statement<span style="color: black;">&#41;</span>
            logger.<span style="color: black;">debug</span><span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;Total Time: %f&quot;</span> % total<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #0908ce;font-weight:bold;">if</span> __name__ == <span style="color: #E04500;">'__main__'</span>:
    <span style="color: #0908ce;font-weight:bold;">from</span> sqlalchemy <span style="color: #0908ce;font-weight:bold;">import</span> *
&nbsp;
    engine= create_engine<span style="color: black;">&#40;</span><span style="color: #E04500;">'sqlite://'</span>, proxy=TimerProxy<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    m1 = MetaData<span style="color: black;">&#40;</span>engine<span style="color: black;">&#41;</span>
    t1 = Table<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;sometable&quot;</span>, m1, 
            Column<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;id&quot;</span>, Integer, primary_key=<span style="color: #6f0005;">True</span><span style="color: black;">&#41;</span>,
            Column<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;data&quot;</span>, String<span style="color: black;">&#40;</span><span style="color: #E04500;">255</span><span style="color: black;">&#41;</span>, nullable=<span style="color: #6f0005;">False</span><span style="color: black;">&#41;</span>,
        <span style="color: black;">&#41;</span>
&nbsp;
    conn = engine.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    m1.<span style="color: black;">create_all</span><span style="color: black;">&#40;</span>conn<span style="color: black;">&#41;</span>
&nbsp;
    conn.<span style="color: black;">execute</span><span style="color: black;">&#40;</span>
        t1.<span style="color: black;">insert</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, 
        <span style="color: black;">&#91;</span><span style="color: black;">&#123;</span><span style="color: #E04500;">&quot;data&quot;</span>:<span style="color: #E04500;">&quot;entry %d&quot;</span> % x<span style="color: black;">&#125;</span> <span style="color: #0908ce;font-weight:bold;">for</span> x <span style="color: #0908ce;font-weight:bold;">in</span> <span style="color: #6f0005;">xrange</span><span style="color: black;">&#40;</span><span style="color: #E04500;">100000</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
    <span style="color: black;">&#41;</span>
&nbsp;
    conn.<span style="color: black;">execute</span><span style="color: black;">&#40;</span>
        t1.<span style="color: #dc143c;">select</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">where</span><span style="color: black;">&#40;</span>t1.<span style="color: black;">c</span>.<span style="color: black;">data</span>.<span style="color: black;">between</span><span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;entry 25&quot;</span>, <span style="color: #E04500;">&quot;entry 7800&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">order_by</span><span style="color: black;">&#40;</span>desc<span style="color: black;">&#40;</span>t1.<span style="color: black;">c</span>.<span style="color: black;">data</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: black;">&#41;</span></code></pre>

<p>Output:</p>
<pre class="wp_syntax"><code>DEBUG:myapp.<span style="color: black;">sqltime</span>:Query: PRAGMA table_info<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;sometable&quot;</span><span style="color: black;">&#41;</span>
DEBUG:myapp.<span style="color: black;">sqltime</span>:Total Time: <span style="color: #E04500;">0.000233</span>
DEBUG:myapp.<span style="color: black;">sqltime</span>:Query: 
CREATE TABLE sometable <span style="color: black;">&#40;</span>
    <span style="color: #6f0005;">id</span> INTEGER NOT NULL, 
    data VARCHAR<span style="color: black;">&#40;</span><span style="color: #E04500;">255</span><span style="color: black;">&#41;</span> NOT NULL, 
    PRIMARY KEY <span style="color: black;">&#40;</span><span style="color: #6f0005;">id</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
DEBUG:myapp.<span style="color: black;">sqltime</span>:Total Time: <span style="color: #E04500;">0.000397</span>
DEBUG:myapp.<span style="color: black;">sqltime</span>:Query: INSERT INTO sometable <span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span> VALUES <span style="color: black;">&#40;</span>?<span style="color: black;">&#41;</span>
DEBUG:myapp.<span style="color: black;">sqltime</span>:Total Time: <span style="color: #E04500;">1.147780</span>
DEBUG:myapp.<span style="color: black;">sqltime</span>:Query: SELECT sometable.<span style="color: #6f0005;">id</span>, sometable.<span style="color: black;">data</span> 
FROM sometable 
WHERE sometable.<span style="color: black;">data</span> BETWEEN ? AND ? ORDER BY sometable.<span style="color: black;">data</span> DESC
DEBUG:myapp.<span style="color: black;">sqltime</span>:Total Time: <span style="color: #E04500;">1.064579</span></code></pre>

<p><code>ConnectionProxy</code> features two methods that can be overridden, <code>execute()</code> and <code>cursor_execute()</code>.  The difference is that the former hooks onto the overall <code>execute()</code> method of <code>Connection</code> and is given the application level arguments, such as the <code>ClauseElement</code> and parameter dictionary, whereas the latter is called at the lower level where we have a string SQL statement and bind parameters compiled and formatted against the specific DBAPI in use.</p>
]]></content:encoded>
			<wfw:commentRss>http://techspot.zzzeek.org/?feed=rss2&amp;p=31</wfw:commentRss>
		</item>
		<item>
		<title>Selecting Booleans</title>
		<link>http://techspot.zzzeek.org/?p=30</link>
		<comments>http://techspot.zzzeek.org/?p=30#comments</comments>
		<pubDate>Tue, 09 Sep 2008 18:29:59 +0000</pubDate>
		<dc:creator>zzzeek</dc:creator>
		
		<category><![CDATA[SQLAlchemy]]></category>

		<guid isPermaLink="false">http://techspot.zzzeek.org/?p=30</guid>
		<description><![CDATA[Ticket 798, allow conjunctions to act as column elements, is complete after a long wait, finally attended to for the great reason that I suddenly needed this feature myself ;).   A few tweaks and we can now talk about asking yes/no questions of our database.

As we head into the 0.5 era of SQLAlchemy, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.sqlalchemy.org/trac/ticket/798">Ticket 798</a>, allow conjunctions to act as column elements, is complete after a long wait, finally attended to for the great reason that I suddenly needed this feature myself ;).   A few tweaks and we can now talk about asking yes/no questions of our database.</p>

<p>As we head into the 0.5 era of SQLAlchemy, one theme is that if we're using the ORM, we're going to need <code>select()</code> constructs a lot less, if at all.  Most things can now be done using <code>Query</code> objects.    The other day, I needed to ask my database a question regarding if some particular data were available, and that's it.  The query needed to be as fast as possible so I wanted to use EXISTS, so that the database needs to only access the first row of the selected rows in order to give an answer.   Additionally, I needed to ask this question of a few different sets of criterion, which could be most efficiently achieved by combining them together into a single statement using OR.  </p>

<p>Using the current trunk of SQLAlchemy 0.5, we can use <code>Query()</code> against boolean values:</p>
<pre class="wp_syntax"><code><span style="color: #0908ce;font-weight:bold;">from</span> sqlalchemy <span style="color: #0908ce;font-weight:bold;">import</span> *
<span style="color: #0908ce;font-weight:bold;">from</span> sqlalchemy.<span style="color: black;">orm</span> <span style="color: #0908ce;font-weight:bold;">import</span> *
engine = create_engine<span style="color: black;">&#40;</span><span style="color: #E04500;">'sqlite://'</span>, echo=<span style="color: #6f0005;">True</span><span style="color: black;">&#41;</span>
Session = scoped_session<span style="color: black;">&#40;</span>sessionmaker<span style="color: black;">&#40;</span>bind=engine<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
true, false = literal<span style="color: black;">&#40;</span><span style="color: #6f0005;">True</span><span style="color: black;">&#41;</span>, literal<span style="color: black;">&#40;</span><span style="color: #6f0005;">False</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: black;">&#40;</span>ret, <span style="color: black;">&#41;</span>, = Session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>true<span style="color: black;">&#41;</span>
<span style="color: #0908ce;font-weight:bold;">print</span> ret</code></pre>

<p>which returns:</p>
<pre class="wp_syntax"><code>True</code></pre>

<p>The question we just asked our SQLite database is <code>SELECT 1</code>, where "1" is SQLite's way of representing <code>true</code> (in Postgres it's <code>true</code>, in MySQL it can be <code>1</code> or <code>true</code>.  Using <code>literal(True)</code> means we don't have to worry about this).  SQLite tells us, "yes, True is True".   Note the way I'm getting the row out of <code>Query</code>.   At the moment that seems to be a fun way to go, but you could also say:</p>
<pre class="wp_syntax"><code>ret, = Session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>true<span style="color: black;">&#41;</span>.<span style="color: black;">one</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></pre>

<p>and of course:</p>
<pre class="wp_syntax"><code>ret = Session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>true<span style="color: black;">&#41;</span>.<span style="color: black;">one</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #E04500;">0</span><span style="color: black;">&#93;</span></code></pre>

<p>We can also ask our database about boolean values combined with OR and AND:</p>
<pre class="wp_syntax"><code>&gt;&gt;&gt; <span style="color: black;">&#40;</span>ret, <span style="color: black;">&#41;</span>, = Session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>or_<span style="color: black;">&#40;</span>true, false<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&gt;&gt;&gt; ret
<span style="color: #6f0005;">True</span>
&nbsp;
&gt;&gt;&gt; <span style="color: black;">&#40;</span>ret, <span style="color: black;">&#41;</span>, = Session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>and_<span style="color: black;">&#40;</span>true, false<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&gt;&gt;&gt; ret
<span style="color: #6f0005;">False</span></code></pre>

<p>To demonstrate <code>EXISTS</code>, let's build a table.   We're using declarative, which is pretty much the only way I roll these days (hey, better late than never....):</p>
<pre class="wp_syntax"><code><span style="color: #0908ce;font-weight:bold;">from</span> sqlalchemy.<span style="color: black;">ext</span>.<span style="color: black;">declarative</span> <span style="color: #0908ce;font-weight:bold;">import</span> declarative_base
Base = declarative_base<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #0908ce;font-weight:bold;">class</span> Keyword<span style="color: black;">&#40;</span>Base<span style="color: black;">&#41;</span>:
    __tablename__ = <span style="color: #E04500;">&quot;keyword&quot;</span>
    <span style="color: #6f0005;">id</span> = Column<span style="color: black;">&#40;</span>Integer, primary_key=<span style="color: #6f0005;">True</span><span style="color: black;">&#41;</span>
    name = Column<span style="color: black;">&#40;</span>String<span style="color: black;">&#40;</span><span style="color: #E04500;">255</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
Base.<span style="color: black;">metadata</span>.<span style="color: black;">create_all</span><span style="color: black;">&#40;</span>engine<span style="color: black;">&#41;</span></code></pre>

<p>One way we could find out if our <code>Keyword</code> table has any of a certain set of keywords, is to do something familiar and ask for a count:</p>
<pre class="wp_syntax"><code>keywords = <span style="color: black;">&#91;</span><span style="color: #E04500;">&quot;beans&quot;</span>, <span style="color: #E04500;">&quot;lentils&quot;</span>, <span style="color: #E04500;">&quot;legumes&quot;</span><span style="color: black;">&#93;</span>
<span style="color: black;">&#40;</span>ret, <span style="color: black;">&#41;</span>, = Session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>func.<span style="color: black;">count</span><span style="color: black;">&#40;</span>Keyword.<span style="color: #6f0005;">id</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: #6f0005;">filter</span><span style="color: black;">&#40;</span>Keyword.<span style="color: black;">name</span>.<span style="color: black;">in_</span><span style="color: black;">&#40;</span>keywords<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></code></pre>

<p>But to eliminate the need for the database to actually count the full set of rows, we can ask it just if any rows at all exist, using the <code>exists()</code> construct:</p>
<pre class="wp_syntax"><code><span style="color: black;">&#40;</span>ret, <span style="color: black;">&#41;</span>, = Session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>exists<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">where</span><span style="color: black;">&#40;</span>Keyword.<span style="color: black;">name</span>.<span style="color: black;">in_</span><span style="color: black;">&#40;</span>keywords<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></code></pre>

<p>Which issues the SQL:</p>
<pre class="wp_syntax"><code><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> * <span style="color: #993333; font-weight: bold;">FROM</span> keyword <span style="color: #993333; font-weight: bold;">WHERE</span> keyword.name <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span>?, ?, ?<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> anon_1</code></pre>

<p>The return value is boolean, indicating True for rows were found, False for no rows were found.  In my case, I was querying among a bunch of tables.   Let's suppose we have a database which represents cookbooks and individual recipes, both of which have lists of keywords associated.  Let's declare that up:</p>
<pre class="wp_syntax"><code>recipe_keywords = Table<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;recipe_keyword&quot;</span>, Base.<span style="color: black;">metadata</span>, 
                    Column<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;recipe_id&quot;</span>, Integer, ForeignKey<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;recipe.id&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>,
                    Column<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;keyword_id&quot;</span>, Integer, ForeignKey<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;keyword.id&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
                    <span style="color: black;">&#41;</span>
&nbsp;
cookbook_keywords = Table<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;cookbook_keyword&quot;</span>, Base.<span style="color: black;">metadata</span>, 
                    Column<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;cookbook_id&quot;</span>, Integer, ForeignKey<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;cookbook.id&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>,
                    Column<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;keyword_id&quot;</span>, Integer, ForeignKey<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;keyword.id&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
                    <span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #0908ce;font-weight:bold;">class</span> Recipe<span style="color: black;">&#40;</span>Base<span style="color: black;">&#41;</span>:
    __tablename__ = <span style="color: #E04500;">&quot;recipe&quot;</span>
    <span style="color: #6f0005;">id</span> = Column<span style="color: black;">&#40;</span>Integer, primary_key=<span style="color: #6f0005;">True</span><span style="color: black;">&#41;</span>
    description = Column<span style="color: black;">&#40;</span>Text<span style="color: black;">&#41;</span>
    keywords = relation<span style="color: black;">&#40;</span>Keyword, secondary=recipe_keywords<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #0908ce;font-weight:bold;">class</span> Cookbook<span style="color: black;">&#40;</span>Base<span style="color: black;">&#41;</span>:
    __tablename__ = <span style="color: #E04500;">&quot;cookbook&quot;</span>
    <span style="color: #6f0005;">id</span> = Column<span style="color: black;">&#40;</span>Integer, primary_key=<span style="color: #6f0005;">True</span><span style="color: black;">&#41;</span>
    description = Column<span style="color: black;">&#40;</span>Text<span style="color: black;">&#41;</span>
    keywords = relation<span style="color: black;">&#40;</span>Keyword, secondary=cookbook_keywords<span style="color: black;">&#41;</span>
&nbsp;
Base.<span style="color: black;">metadata</span>.<span style="color: black;">create_all</span><span style="color: black;">&#40;</span>engine<span style="color: black;">&#41;</span></code></pre>

<p>The above schema defines a <code>recipe</code> and a <code>cookbook</code> table, each of which relate to <code>keyword</code> via the <code>recipe_keyword</code> or <code>cookbook_keyword</code> association tables, respectively.   </p>

<p>The question of "Do any recipes feature any of our above three keywords?" can be answered by:</p>
<pre class="wp_syntax"><code><span style="color: black;">&#40;</span>ret, <span style="color: black;">&#41;</span>, = Session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>
    exists<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">where</span><span style="color: black;">&#40;</span>Recipe.<span style="color: #6f0005;">id</span>==recipe_keywords.<span style="color: black;">c</span>.<span style="color: black;">recipe_id</span><span style="color: black;">&#41;</span>.
            <span style="color: black;">where</span><span style="color: black;">&#40;</span>recipe_keywords.<span style="color: black;">c</span>.<span style="color: black;">keyword_id</span>==Keyword.<span style="color: #6f0005;">id</span><span style="color: black;">&#41;</span>.
            <span style="color: black;">where</span><span style="color: black;">&#40;</span>Keyword.<span style="color: black;">name</span>.<span style="color: black;">in_</span><span style="color: black;">&#40;</span>keywords<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#41;</span></code></pre>

<p>Above we ask "do any rows exist, where the ID of the <code>recipe</code> table matches the recipe ID of the <code>recipe_keywords</code> table, and the keyword ID of the <code>recipe_keywords</code> table matches the ID of a <code>keyword</code> table row, and the name of the keyword is in the list <code>["beans", "lentils", "legumes"]</code>".  SQL is:</p>
<pre class="wp_syntax"><code><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> * 
<span style="color: #993333; font-weight: bold;">FROM</span> recipe, recipe_keyword, keyword 
<span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #66cc66;">&#40;</span>recipe.id = recipe_keyword.recipe_id <span style="color: #993333; font-weight: bold;">AND</span> recipe_keyword.keyword_id = keyword.id<span style="color: #66cc66;">&#41;</span> 
<span style="color: #993333; font-weight: bold;">AND</span> keyword.name <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span>?, ?, ?<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> anon_1</code></pre>

<p>Spelling out the full join from <code>Recipe</code> to <code>Keyword</code> above is a little bit verbose.   We have the option to let SQLAlchemy create this for us using the <code>Recipe.keywords</code> relation already set up, using the ORM level <code>join()</code> function, which provides direct access to the ORM's join algorithm:</p>
<pre class="wp_syntax"><code><span style="color: #0908ce;font-weight:bold;">from</span> sqlalchemy.<span style="color: black;">orm</span> <span style="color: #0908ce;font-weight:bold;">import</span> join
<span style="color: black;">&#40;</span>ret, <span style="color: black;">&#41;</span>, = Session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>
        exists<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">select_from</span><span style="color: black;">&#40;</span>join<span style="color: black;">&#40;</span>Recipe, Keyword, Recipe.<span style="color: black;">keywords</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.
                <span style="color: black;">where</span><span style="color: black;">&#40;</span>Keyword.<span style="color: black;">name</span>.<span style="color: black;">in_</span><span style="color: black;">&#40;</span>keywords<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#41;</span></code></pre>

<p>This generates:</p>
<pre class="wp_syntax"><code><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> * 
<span style="color: #993333; font-weight: bold;">FROM</span> recipe <span style="color: #993333; font-weight: bold;">JOIN</span> recipe_keyword <span style="color: #993333; font-weight: bold;">AS</span> recipe_keyword_1 <span style="color: #993333; font-weight: bold;">ON</span> 
recipe.id = recipe_keyword_1.recipe_id <span style="color: #993333; font-weight: bold;">JOIN</span> keyword <span style="color: #993333; font-weight: bold;">ON</span> 
keyword.id = recipe_keyword_1.keyword_id 
<span style="color: #993333; font-weight: bold;">WHERE</span> keyword.name <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span>?, ?, ?<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> anon_1</code></pre>

<p>We now know how to ask the database if it has any <code>recipe</code> rows which relate to a given set of keyword names.  To ask the database if it has any <code>cookbook</code> rows or <code>recipe</code> rows matching our keywords at the same time, we can double up on <code>exists()</code> clauses using <code>or_()</code>:</p>
<pre class="wp_syntax"><code><span style="color: black;">&#40;</span>ret, <span style="color: black;">&#41;</span>, = Session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>or_<span style="color: black;">&#40;</span>
        exists<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">select_from</span><span style="color: black;">&#40;</span>join<span style="color: black;">&#40;</span>Recipe, Keyword, Recipe.<span style="color: black;">keywords</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.
                <span style="color: black;">where</span><span style="color: black;">&#40;</span>Keyword.<span style="color: black;">name</span>.<span style="color: black;">in_</span><span style="color: black;">&#40;</span>keywords<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>,
&nbsp;
        exists<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">select_from</span><span style="color: black;">&#40;</span>join<span style="color: black;">&#40;</span>Cookbook, Keyword, Cookbook.<span style="color: black;">keywords</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.
            <span style="color: black;">where</span><span style="color: black;">&#40;</span>Keyword.<span style="color: black;">name</span>.<span style="color: black;">in_</span><span style="color: black;">&#40;</span>keywords<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></code></pre>

<p>At this point, our eyes begin to glaze over when viewing the SQL itself.  But that's fine; just remember that whenever this happens, somewhere in the world another "ORM's aren't worth it" blog post fades away:</p>
<pre class="wp_syntax"><code><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">EXISTS</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> * 
<span style="color: #993333; font-weight: bold;">FROM</span> recipe <span style="color: #993333; font-weight: bold;">JOIN</span> recipe_keyword <span style="color: #993333; font-weight: bold;">AS</span> recipe_keyword_1 <span style="color: #993333; font-weight: bold;">ON</span> recipe.id = recipe_keyword_1.recipe_id  
<span style="color: #993333; font-weight: bold;">JOIN</span> keyword <span style="color: #993333; font-weight: bold;">ON</span> keyword.id = recipe_keyword_1.keyword_id 
<span style="color: #993333; font-weight: bold;">WHERE</span> keyword.name <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span>?, ?, ?<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">OR</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">EXISTS</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> * 
<span style="color: #993333; font-weight: bold;">FROM</span> cookbook <span style="color: #993333; font-weight: bold;">JOIN</span> cookbook_keyword <span style="color: #993333; font-weight: bold;">AS</span> cookbook_keyword_1 <span style="color: #993333; font-weight: bold;">ON</span> 
cookbook.id = cookbook_keyword_1.cookbook_id <span style="color: #993333; font-weight: bold;">JOIN</span> keyword <span style="color: #993333; font-weight: bold;">ON</span> 
keyword.id = cookbook_keyword_1.keyword_id 
<span style="color: #993333; font-weight: bold;">WHERE</span> keyword.name <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span>?, ?, ?<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> anon_1</code></pre>

<p>Those readers who are familiar with some of SQLA's advanced Query operators might recognize that the above EXISTS queries look a lot like an <code>any()</code> expression.    This is because, they are!  Though in this case, almost.  As a review, an <code>any()</code> expression creates an EXISTS clause which is correlated with the enclosing query, such as:</p>
<pre class="wp_syntax"><code>rows = Session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>Recipe<span style="color: black;">&#41;</span>.<span style="color: #6f0005;">filter</span><span style="color: black;">&#40;</span>Recipe.<span style="color: black;">keywords</span>.<span style="color: black;">any</span><span style="color: black;">&#40;</span>Keyword.<span style="color: black;">name</span>.<span style="color: black;">in_</span><span style="color: black;">&#40;</span>keywords<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></pre>

<p>This query produces a regular <code>SELECT</code> from the <code>recipe</code> table, then embeds a correlated <code>EXISTS</code> inside the WHERE clause:</p>
<pre class="wp_syntax"><code><span style="color: #993333; font-weight: bold;">SELECT</span> recipe.id <span style="color: #993333; font-weight: bold;">AS</span> recipe_id, recipe.description <span style="color: #993333; font-weight: bold;">AS</span> recipe_description 
<span style="color: #993333; font-weight: bold;">FROM</span> recipe 
<span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">1</span> 
<span style="color: #993333; font-weight: bold;">FROM</span> recipe_keyword, keyword 
<span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #66cc66;">&#40;</span>recipe.id = recipe_keyword.recipe_id <span style="color: #993333; font-weight: bold;">AND</span> keyword.id = recipe_keyword.keyword_id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AND</span>
keyword.name <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span>?, ?, ?<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></code></pre>

<p>When <code>any()</code> is used, it explicitly states that the <code>exists()</code> clause should <code>correlate()</code> to the <code>recipe</code> table, which allows it to work in scenarios where SQLAlchemy's usual "auto" correlation cannot make the right decision (we have tests which illustrate this).  So to use <code>any()</code> in our "column-based" approach, we just need to turn off that correlation using <code>correlate(None)</code>.  Our "recipes/cookbooks which exist" query can be stated as:</p>
<pre class="wp_syntax"><code><span style="color: black;">&#40;</span>ret, <span style="color: black;">&#41;</span>, = Session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>or_<span style="color: black;">&#40;</span>
    Recipe.<span style="color: black;">keywords</span>.<span style="color: black;">any</span><span style="color: black;">&#40;</span>Keyword.<span style="color: black;">name</span>.<span style="color: black;">in_</span><span style="color: black;">&#40;</span>keywords<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">correlate</span><span style="color: black;">&#40;</span><span style="color: #6f0005;">None</span><span style="color: black;">&#41;</span>,
    Cookbook.<span style="color: black;">keywords</span>.<span style="color: black;">any</span><span style="color: black;">&#40;</span>Keyword.<span style="color: black;">name</span>.<span style="color: black;">in_</span><span style="color: black;">&#40;</span>keywords<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">correlate</span><span style="color: black;">&#40;</span><span style="color: #6f0005;">None</span><span style="color: black;">&#41;</span>
    <span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></code></pre>

<p>While the <code>any()</code> approach above is nice, the correlation part of it has me preferring the more explicit <code>exists()</code> version.</p>
]]></content:encoded>
			<wfw:commentRss>http://techspot.zzzeek.org/?feed=rss2&amp;p=30</wfw:commentRss>
		</item>
		<item>
		<title>Ajax the Mako Way</title>
		<link>http://techspot.zzzeek.org/?p=29</link>
		<comments>http://techspot.zzzeek.org/?p=29#comments</comments>
		<pubDate>Mon, 01 Sep 2008 23:15:38 +0000</pubDate>
		<dc:creator>zzzeek</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://techspot.zzzeek.org/?p=29</guid>
		<description><![CDATA[My previous post (updated!) demonstrated how Mako's "defs with embedded content" feature was used to build a library of form tags, keeping all HTML and layout within templates, as well as a succinct method of linking them to form validation and data state.   The "def with embedded content", a feature derived from HTML::Mason, [...]]]></description>
			<content:encoded><![CDATA[<p>My <a href="?p=28">previous post</a> (updated!) demonstrated how Mako's "defs with embedded content" feature was used to build a library of form tags, keeping all HTML and layout within templates, as well as a succinct method of linking them to form validation and data state.   The "def with embedded content", a feature derived from HTML::Mason, is one feature that makes Mako highly unique in the Python world.   The form demo also illustrated another unique feature, which is the ability to "export" the functionality of a def (essentially a subcomponent of a page) to other templates, without any dependency on inheritance or other structural relationship.   Defs with embeddable content and exportable defs are two features I would never want to do without, which is why I ported HTML::Mason to Myghty, and later created Mako for Python.</p>

<p>A lesser known capability of the def is that they can be called not just by other templates but by any arbitrary caller, such as a controller.   As it turns out, this capability is ideal in conjunction with asynchronous requests as well, a use case that didn't even exist when HTML::Mason was first created.   Here I'll demonstrate my favorite way to do Ajax with Pylons and the unbelievably excellent <a href="http://jquery.com/">jQuery</a>.  We'll introduce a new <code>render()</code> function that IMO should be part of Pylons, the same way as <code>render_mako()</code>.   </p>

<p>An asynchronous HTTP request is often used to render part of the page while leaving the rest unchanged, typically by taking the output of the HTTP request and rendering it into a DOM element.  Jquery code such as the following can achieve this:</p>
<pre class="wp_syntax"><code>$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;#some_element&quot;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">load</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;/datafeed&quot;</span><span style="color: #66cc66;">&#41;</span>;</code></pre>

<p>The above statement will render the output of the URI <code>/datafeed</code> into the DOM element with the id <code>some_element</code>.    In Pylons, a controller and associated template would provide the output for the <code>/datafeed</code> URI, which would be HTML content forming a portion of the larger webpage.</p>

<p>In our example, we'll build a "pager" display which displays multiple pages of a document, one at a time, using the <code>load()</code> method to load new pages.    One way we might do this looks like this:</p>
<pre class="wp_syntax"><code>&lt;div id=&quot;display&quot;&gt;&lt;/div&gt;
&lt;a href=&quot;javascript:showpage(1)&quot;&gt;1&lt;/a&gt; 
&lt;a href=&quot;javascript:showpage(2)&quot;&gt;2&lt;/a&gt; 
&lt;a href=&quot;javascript:showpage(3)&quot;&gt;3&lt;/a&gt; 
&nbsp;
&lt;script&gt;
    function showpage(num) {
        $(&quot;#display&quot;).load(&quot;/page/read/&quot; + num);
    }
    showpage(1);
&lt;/script&gt;</code></pre>

<p>Above, we define <code>display</code>, which is a div where the pages render.   Some javascript code defines the <code>showpage()</code> function, which given a page number calls the jQuery <code>load()</code> function to load the content from the page-appropriate URI into the div.   Three links to three different pages each link to <code>showpage()</code>, given different page numbers.</p>

<p>In this version, the <code>/page/read</code> controller would probably define a separate template of some kind in order to format a the data, so the layout of what goes inside of <code>display</code> is elsewhere.  Additionally, the initial display of the full layout requires two HTTP requests, one to deliver the enclosing layout and another to load the formatted content within <code>display</code>.</p>

<p>When using Mako, we often want to group together related components of display within a single file.  The <code>&lt;%def&gt;</code> tag makes this possible - a compound layout of small, highly interrelated components need not be spread across many files with small amounts of HTML in each; they can all be defined together, which can cut down on clutter and speed up development.</p>

<p>Such as, if we built the above display entirely without any asynchronous functionality, we might say:</p>
<pre class="wp_syntax"><code>&lt;div id=&quot;display&quot;&gt;
    ${showpage(c.page)}
&lt;/div&gt;
&lt;a href=&quot;/page/read/1&quot;&gt;1&lt;/a&gt;
&lt;a href=&quot;/page/read/2&quot;&gt;2&lt;/a&gt;
&lt;a href=&quot;/page/read/3&quot;&gt;3&lt;/a&gt;
&nbsp;
&lt;%def name=&quot;showpage(page)&quot;&gt;
&lt;div class=&quot;page&quot;&gt;
    &lt;div class=&quot;pagenum&quot;&gt;Page: ${page.number}&lt;/div&gt;
    &lt;h3&gt;${page.title}&lt;/h3&gt;
&nbsp;
    &lt;pre&gt;${page.content}&lt;/pre&gt;
&lt;/div&gt;
&lt;/%def&gt;</code></pre>

<p>The above approach again defines <code>showpage()</code>, but it's now a server-side Mako def, which receives a single <code>Page</code> object as the thing to be rendered.   The output is first displayed using the <code>Page</code> object placed at <code>c.page</code> by the controller, and subsequent controller requests re-render the full layout with the appropriate <code>Page</code> represented.</p>

<p>The missing link here is to use both of the above approaches at the same time - render the first <code>Page</code> object into the div without using an asynchronous request, allow subsequent <code>Page</code> requests to be rendered via Ajax, and finally to have the whole layout defined in a single file.  For that, we need a new Pylons render function, which looks like this:</p>
<pre class="wp_syntax"><code><span style="color: #0908ce;font-weight:bold;">def</span> render_def<span style="color: black;">&#40;</span>template_name, name, **kwargs<span style="color: black;">&#41;</span>:
    globs = pylons_globals<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #0908ce;font-weight:bold;">if</span> kwargs:
        globs = globs.<span style="color: #dc143c;">copy</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        globs.<span style="color: black;">update</span><span style="color: black;">&#40;</span>kwargs<span style="color: black;">&#41;</span>
&nbsp;
    template = globs<span style="color: black;">&#91;</span><span style="color: #E04500;">'app_globals'</span><span style="color: black;">&#93;</span>.<span style="color: black;">mako_lookup</span>.<span style="color: black;">get_template</span><span style="color: black;">&#40;</span>template_name<span style="color: black;">&#41;</span>.<span style="color: black;">get_def</span><span style="color: black;">&#40;</span>name<span style="color: black;">&#41;</span>
    <span style="color: #0908ce;font-weight:bold;">return</span> template.<span style="color: black;">render</span><span style="color: black;">&#40;</span>**globs<span style="color: black;">&#41;</span></code></pre>

<p>The above <code>render_def()</code> function is adapted from the standard Pylons boilerplate for building render functions.  It's virtually the same as <code>render_mako()</code> except we're calling the extra <code>get_def()</code> method from the Mako <code>Template</code> object, and we're also passing some <code>**kwargs</code> straight to the def in addition to the standard Pylons template globals.   A refined approach might involve building a <code>render_mako()</code> function that has the functionality to render both full <code>Template</code> objects as well as individual <code>&lt;%def&gt;</code> objects based on arguments; but we'll keep them separate for now.</p>

<p>With <code>render_def()</code>, the Ajax version of our page now looks like:</p>
<pre class="wp_syntax"><code>&lt;div id=&quot;display&quot;&gt;
     ${showpage(c.page)}
&lt;/div&gt;
&lt;a href=&quot;javascript:showpage(1)&quot;&gt;1&lt;/a&gt; 
&lt;a href=&quot;javascript:showpage(2)&quot;&gt;2&lt;/a&gt; 
&lt;a href=&quot;javascript:showpage(3)&quot;&gt;3&lt;/a&gt; 
&nbsp;
&lt;script&gt;
    function showpage(num) {
        $(&quot;#display&quot;).load(&quot;/page/read/&quot; + num);
    }
&lt;/script&gt;
&nbsp;
&lt;%def name=&quot;showpage(page)&quot;&gt;
&lt;div class=&quot;page&quot;&gt;
    &lt;div class=&quot;pagenum&quot;&gt;Page: ${page.number}&lt;/div&gt;
    &lt;h3&gt;${page.title}&lt;/h3&gt;
&nbsp;
    &lt;pre&gt;${page.content}&lt;/pre&gt;
&lt;/div&gt;
&lt;/%def&gt;</code></pre>

<p>Note above that there are <em>two</em> showpage functions; one is a Mako def, callable during the server's rendering of the template, the other a Javascript function which uses jQuery to issue a new request to load new content.   The <code>/page/read</code> controller calls the <code>showpage()</code> def directly as its returned template.   The net effect is that the server-side version of <code>showpage()</code> dual purposes itself in two different contexts; as a server-side component which participates in the composition of an enclosing template render, and as a "standalone" template which delivers new versions of its layout into the same overall display within its own HTTP request.</p>

<p>The controller, which locates <code>Page</code> objects using a simple SQLAlchemy model, in its entirety:</p>
<pre class="wp_syntax"><code><span style="color: #0908ce;font-weight:bold;">class</span> PageController<span style="color: black;">&#40;</span>BaseController<span style="color: black;">&#41;</span>:
    <span style="color: #0908ce;font-weight:bold;">def</span> index<span style="color: black;">&#40;</span><span style="color: #6f0005;">self</span><span style="color: black;">&#41;</span>:
        c.<span style="color: black;">number_of_pages</span> = Session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>Page<span style="color: black;">&#41;</span>.<span style="color: black;">count</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        c.<span style="color: black;">page</span> = Session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>Page<span style="color: black;">&#41;</span>.<span style="color: #6f0005;">filter</span><span style="color: black;">&#40;</span>Page.<span style="color: black;">number</span>==<span style="color: #E04500;">1</span><span style="color: black;">&#41;</span>.<span style="color: black;">one</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #0908ce;font-weight:bold;">return</span> render<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;/page.mako&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #0908ce;font-weight:bold;">def</span> read<span style="color: black;">&#40;</span><span style="color: #6f0005;">self</span>, <span style="color: #6f0005;">id</span><span style="color: black;">&#41;</span>:
        pagenum = <span style="color: #6f0005;">int</span><span style="color: black;">&#40;</span><span style="color: #6f0005;">id</span><span style="color: black;">&#41;</span>
&nbsp;
        page = Session.<span style="color: black;">query</span><span style="color: black;">&#40;</span>Page<span style="color: black;">&#41;</span>.<span style="color: #6f0005;">filter</span><span style="color: black;">&#40;</span>Page.<span style="color: black;">number</span>==pagenum<span style="color: black;">&#41;</span>.<span style="color: black;">one</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #0908ce;font-weight:bold;">return</span> render_def<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;/page.mako&quot;</span>, <span style="color: #E04500;">&quot;showpage&quot;</span>, page=page<span style="color: black;">&#41;</span></code></pre>

<p>I've packaged the whole thing as a <a href="/ajaxdemo/ajax.tar.gz">demo</a> application (using Pylons 0.9.7 and SQLAlchemy 0.5), which pages through a document we all should be well familiar with.</p>
]]></content:encoded>
			<wfw:commentRss>http://techspot.zzzeek.org/?feed=rss2&amp;p=29</wfw:commentRss>
		</item>
		<item>
		<title>Better Form Generation with Mako and Pylons</title>
		<link>http://techspot.zzzeek.org/?p=28</link>
		<comments>http://techspot.zzzeek.org/?p=28#comments</comments>
		<pubDate>Tue, 01 Jul 2008 19:05:55 +0000</pubDate>
		<dc:creator>zzzeek</dc:creator>
		
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://techspot.zzzeek.org/?p=28</guid>
		<description><![CDATA[Update - The formhelpers demo is updated and is production ready.  See the end of the post for details.

If you're a web developer in New York City, unless you work here, here or maybe here, you're probably not using Python for primary development (if you are, please post your company here).    [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update</strong> - The formhelpers demo is updated and is production ready.  See the <a href="#mako_forms_update_1">end of the post</a> for details.</p>

<p>If you're a web developer in New York City, unless you work <a href="http://www.daylife.com/">here</a>, <a href="http://topp.openplans.org/project-home">here</a> or maybe <a href="http://www.google.com">here</a>, you're probably not using Python for primary development (if you are, please post your company <a href="http://www.nycpython.org/PythonCompanies">here</a>).    Since I'm not a PHP monkey or a Microsoftie,  everywhere I work they're using <a href="http://struts.apache.org">Struts</a>, which is where the dust has settled around Java Server Pages (with honorable mentions to <a href="http://www.springframework.org/">Spring MVC</a> and <a href="http://java.sun.com/javaee/javaserverfaces/">JSF</a>).   </p>

<p>I'm in a position where I might be able to push Python technology for a project or two, which have until now been built on Struts 1, the most common version of Struts even though Struts 2 is considerably nicer.   So I wanted to see where <a href="http://pylonshq.com">Pylons</a> is at with form rendering and processing these days.  Most importantly, I wanted to ensure that layout is accomplished plainly within a template with no module-embedded HTML and no "magic generation" of forms from classes or other datastructures, and that the cycle of data from form to controller back to form again is similarly simple and obvious.   Most projects in New York are the kind that get handed off to totally different people when complete, or even just 80% complete since you've been put onto something else, for remaining development and future enhancements.  Code handoffs are extremely common, so it can't be overstated how much more important it is to be obvious than to be DRY.  This is a big reason that tedious, plodding approaches like Struts and PHP are so popular - through raw verbosity they discourage opaque ways of doing things.   Overly clever, data-driven rendering solutions that nobody can understand or extend (and are usually broken, anyway) are basically what gets thrown away and rewritten by the next team.</p>

<p>In developing <a href="http://www.makotemplates.org">Mako</a>, a primary goal was to make a super-nice version of a particular "component" pattern which I had used for years primarily with <a href="http://www.masonhq.com/">HTML::Mason</a> which for me provides a "sweet spot" of obviousness, agility, and succinctness.  The focus is around the ability to create "tag libraries" which interact easily with a server-parsed templating language, and which can be implemented within templates themselves.   In JSP development, taglibs are now the standard way to indicate dynamic areas of templates, but while they look pretty clean, they are painful to implement (requiring HTML embedded in hand-crafted classes, a few dozen XML pushups for every tag you add, and the obligatory application restart whenever they change), and the <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JSPIntro7.html">EL</a> and <a href="http://struts.apache.org/2.0.11.1/docs/ognl.html">OGNL</a> expressions which are standard within taglibs interact terribly with straight Java code.  </p>

<p>Mako allows the creation of tags which can be arbitrarily nested and interactive with one another via the <code>&lt;%def&gt;</code> construct, in combination with the <code>&lt;%call&gt;</code> tag.  It's been my observation that the <code>&lt;%call&gt;</code> tag as well as the usage of nesting-aware <code>&lt;%defs&gt;</code> hasn't caught on yet, as the examples in the docs are a little dense, so here I will seek to demystify it a bit.</p>

<p>Pylons currently recommends a decent approach to rendering forms, using <a href="http://docs.pylonshq.com/thirdparty/webhelpers.html#form-tags">Form Tags</a> which are essentially little functions you can embed in your template to render standard form elements.  The handling of the form at the controller level uses <a href="http://formencode.org">FormEncode</a> and routes validation errors through <a href="http://formencode.org/htmlfill.html">htmlfill</a>.  My approach modifies this to use Mako tags to build a site-specific taglib around the webhelpers tags and adds an explicit interaction between those tags and the controller, in a manner similar to a Struts form handler, which replaces <code>htmlfill</code> and allows all layout, including the layout of validation error messages, using the same template system.  It also adds a preprocessor that illustrates how to build custom tags in Mako which look as nice as the built-in ones.</p>

<p>A tar.gz of the approach, which at this point should be regarded strictly as a proof of concept, can be downloaded <a href="http://techspot.zzzeek.org/formhelpers/formhelpers.tar.gz">here</a> (works against Pylons 0.9.7), which contains three templates each illustrating a different approach to laying out the form.  The three approaches are raw webhelpers with htmlfill, the <code>&lt;%call&gt;</code> tag approach, and finally using the "custom tag" approach.  The final result, present in the file <code>templates/mako_helpers.html</code>, looks like this:</p>
<pre class="wp_syntax"><code>&lt;%namespace name=&quot;form&quot; file=&quot;/form_tags.mako&quot;/&gt;
&nbsp;
&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;
   &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;Mako Form Helpers&lt;/title&gt;
  &lt;link rel=&quot;stylesheet&quot; href=&quot;/style.css&quot; type=&quot;text/css&quot; /&gt;
&lt;/head&gt;
&lt;body&gt;
&nbsp;
&lt;h3&gt;Using Mako Helpers&lt;/h3&gt;
&nbsp;
&lt;%form:form controller='comment' action='mako_post'&gt;
&lt;table&gt;
    &lt;tr&gt;
        &lt;th colspan=&quot;2&quot;&gt;Submit your Comment&lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Your Name:&lt;/td&gt;
        &lt;td&gt;&lt;%form:text name=&quot;name&quot;/&gt;&lt;/td&gt;
    &lt;/tr&gt;
&nbsp;
    &lt;tr&gt;
        &lt;td&gt;How did you hear about this site ?&lt;/td&gt;
        &lt;td&gt;
            &lt;%form:select name=&quot;heard&quot;&gt;
                &lt;%form:option value=&quot;&quot; selected=&quot;True&quot;&gt;None&lt;/%form:option&gt;
                % for desc, value in c.heard_choices:
                    &lt;%form:option value=&quot;${value}&quot;&gt;${desc}&lt;/%form:option&gt;
                % endfor
            &lt;/%form:select&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
&nbsp;
    &lt;tr&gt;
        &lt;td&gt;Comment:&lt;/td&gt;
        &lt;td&gt;&lt;%form:textarea name=&quot;comment&quot;/&gt;&lt;/td&gt;
    &lt;/tr&gt;
&nbsp;
    &lt;tr&gt;
        &lt;td colspan=&quot;2&quot;&gt;&lt;%form:submit/&gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;/%form:form&gt;
&nbsp;
&lt;/body&gt;
&lt;/html&gt;</code></pre>

<p>Where of note are the Mako-like <code>&lt;%form:foo&gt;</code> tags that aren't part of Mako !   A short preprocessor is applied to the source file which turns a tag like <code>&lt;%form:foo&gt;</code> into <code>&lt;%call expr="foo()"&gt;</code> at template compile time.  I.e., a tag used above as:</p>
<pre class="wp_syntax"><code>&lt;%form:textarea name=&quot;comment&quot;/&gt;</code></pre>

<p>is preprocessed into raw Mako code:</p>
<pre class="wp_syntax"><code>&lt;%call expr=&quot;form.textarea(name='comment')&quot;/&gt;</code></pre>

<p>The <code>%call</code> tag invokes the <code>textarea</code> def inside the <code>form</code> namespace, which is defined in the file <code>form_tags.mako</code>.  The def for <code>textarea</code> looks like:</p>
<pre class="wp_syntax"><code>&lt;%def name=&quot;textarea(name, default=None, **attrs)&quot;&gt;\
&lt;%doc&gt;
    Render an HTML &lt;textarea&gt;&lt;/textarea&gt; tag pair with embedded content.
&lt;/%doc&gt;\
${form_errors(name)}\
${h.textarea(name, content=request.params.get(name, default), **attrs)}\
&lt;/%def&gt;</code></pre>

<p>Above, the <code>$form_errors(name)</code> is a def call used for reporting validation messages.    The point of <code>form_tags.mako</code> is that all the form tags and their layout is plainly visible and easily customized.   Multiple versions of the file can be used in one application, providing different form layouts for different areas.   The fact that it uses the <code>h</code> helper to render the actual HTML for each form control is also arbitrary; you could just as well implement the <code>&lt;textarea&gt;</code> source directly within the def if some special treatment were needed.</p>

<p>The demo also contains a modified version of Pylons' <code>@validate</code> decorator.  Usage is mostly the same, except the <code>form</code> parameter is replaced by the more direct <code>input_controller</code> parameter, which is the method used for input:</p>
<pre class="wp_syntax"><code><span style="color: #0908ce;font-weight:bold;">from</span> formhelpers.<span style="color: black;">lib</span>.<span style="color: black;">mako_forms</span> <span style="color: #0908ce;font-weight:bold;">import</span> validate as mako_validate
&nbsp;
<span style="color: #0908ce;font-weight:bold;">class</span> CommentController<span style="color: black;">&#40;</span>BaseController<span style="color: black;">&#41;</span>:
    <span style="color: #0908ce;font-weight:bold;">def</span> index<span style="color: black;">&#40;</span><span style="color: #6f0005;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #0908ce;font-weight:bold;">return</span> render<span style="color: black;">&#40;</span><span style="color: #E04500;">'/mako_helpers.html'</span><span style="color: black;">&#41;</span>
&nbsp;
    @mako_validate<span style="color: black;">&#40;</span>schema=CommentForm, input_controller=index<span style="color: black;">&#41;</span>
    <span style="color: #0908ce;font-weight:bold;">def</span> mako_post<span style="color: black;">&#40;</span><span style="color: #6f0005;">self</span><span style="color: black;">&#41;</span>:
        c.<span style="color: black;">name</span> = <span style="color: #6f0005;">self</span>.<span style="color: black;">form_result</span><span style="color: black;">&#91;</span><span style="color: #E04500;">'name'</span><span style="color: black;">&#93;</span>
        <span style="color: #0908ce;font-weight:bold;">return</span> render<span style="color: black;">&#40;</span><span style="color: #E04500;">'/thanks.html'</span><span style="color: black;">&#41;</span></code></pre>

<p>Where above, <code>mako_post</code> hits the validator, and on an invalid exception the <code>index</code> controller method is called instead.  Validation errors are placed in <code>self.form_errors</code> as well as <code>c.form_errors</code> for template access.  The validator as well as the preprocessor are defined in <code>lib/mako_forms.py</code>.</p>

<p>That's pretty much all there is to it at this point, a few folks on #pylons seem enthused about it, so perhaps this can be turned into something more formally available and/or recommended when implementing a Pylons/Mako application.</p>

<p><a name="mako_forms_update_1"></a><strong>UPDATE</strong></p>

<p>I've refined the formhelpers demo with a @validate function tailored to a single usage pattern (<a href="http://techspot.zzzeek.org/formhelpers/formhelpers.tar.gz">download</a>).  Each form now has a name, which identifies its place on <code>c</code>, such as:</p>
<pre class="wp_syntax"><code>&lt;%form:form name=&quot;comment_form&quot; controller='comment' action='post'&gt;</code></pre>

<p>The controller now places a <code>comment_form</code> dictionary on <code>c</code> in all cases, which the <code>@validate</code> function takes care of on the post side:</p>
<pre class="wp_syntax"><code>@validate<span style="color: black;">&#40;</span><span style="color: #E04500;">&quot;comment_form&quot;</span>, CommentForm, input_controller=index<span style="color: black;">&#41;</span>
<span style="color: #0908ce;font-weight:bold;">def</span> post<span style="color: black;">&#40;</span><span style="color: #6f0005;">self</span><span style="color: black;">&#41;</span>:
    c.<span style="color: black;">name</span> = <span style="color: #6f0005;">self</span>.<span style="color: black;">form_result</span><span style="color: black;">&#91;</span><span style="color: #E04500;">'name'</span><span style="color: black;">&#93;</span>
    <span style="color: #0908ce;font-weight:bold;">return</span> render<span style="color: black;">&#40;</span><span style="color: #E04500;">'/thanks.html'</span><span style="color: black;">&#41;</span></code></pre>

<p>The hacky methodology of relating the <code>&lt;%form:option&gt;</code> tag to its parent <code>&lt;%form:select&gt;</code> tag has also been replaced with something reasonable.</p>

<p>This version of formhelpers is production ready.</p>

<p>As far as comments regarding <code>@rest.dispatch_on</code> and forcing a GET to accomodate it, I think that's kind of ugly since I don't really believe in "virtual requests", which is one reason I rewrote the decorator in the first place (i.e., to remove the "re-get" aspect of it).  If you are dual-purposing your <code>index()</code> method to display the form on GET as well as to re-display on POST, then <code>index()</code> needs to accommodate both methods.   Otherwise you can break <code>index()</code> out into <code>index()</code> and <code>_display_index()</code> and have <code>_display_index()</code> be your <code>input_controller</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://techspot.zzzeek.org/?feed=rss2&amp;p=28</wfw:commentRss>
		</item>
		<item>
		<title>SQLAlchemy code swarm</title>
		<link>http://techspot.zzzeek.org/?p=27</link>
		<comments>http://techspot.zzzeek.org/?p=27#comments</comments>
		<pubDate>Wed, 25 Jun 2008 18:38:55 +0000</pubDate>
		<dc:creator>zzzeek</dc:creator>
		
		<category><![CDATA[SQLAlchemy]]></category>

		<guid isPermaLink="false">http://techspot.zzzeek.org/?p=27</guid>
		<description><![CDATA[Django's already got one, and Brian Rosner made one for us too: link.   SQLA's pre-release development is apparent here which is why it floats around "zzzeek" for so long.
]]></description>
			<content:encoded><![CDATA[<p>Django's already got one, and Brian Rosner made one for us too: <a href="http://vimeo.com/1227290">link</a>.   SQLA's pre-release development is apparent here which is why it floats around "zzzeek" for so long.</p>
]]></content:encoded>
			<wfw:commentRss>http://techspot.zzzeek.org/?feed=rss2&amp;p=27</wfw:commentRss>
		</item>
	</channel>
</rss>
