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

« back to all changes in this revision

Viewing changes to doc/orm/tutorial.html

  • Committer: Bazaar Package Importer
  • Author(s): Piotr Ożarowski
  • Date: 2011-08-01 23:18:16 UTC
  • mfrom: (1.4.15 upstream) (16.1.14 experimental)
  • Revision ID: james.westby@ubuntu.com-20110801231816-6lx797pi3q1fpqst
Tags: 0.7.2-1
* New upstream release
* Bump minimum required python-mako version to 0.4.1 (closes: 635898)

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
        
8
8
        <title>
9
9
                Object Relational Tutorial
10
 
             &mdash; SQLAlchemy 0.6.8 Documentation</title>
 
10
             &mdash; SQLAlchemy 0.7 Documentation</title>
11
11
        
12
12
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
13
13
    <link rel="stylesheet" href="../_static/docs.css" type="text/css" />
15
15
    <script type="text/javascript">
16
16
      var DOCUMENTATION_OPTIONS = {
17
17
          URL_ROOT:    '../',
18
 
          VERSION:     '0.6.8',
 
18
          VERSION:     '0.7.2',
19
19
          COLLAPSE_MODINDEX: false,
20
20
          FILE_SUFFIX: '.html'
21
21
      };
27
27
    <link rel="index" title="Index" href="../genindex.html" />
28
28
    <link rel="search" title="Search" href="../search.html" />
29
29
        <link rel="copyright" title="Copyright" href="../copyright.html" />
30
 
    <link rel="top" title="SQLAlchemy 0.6.8 Documentation" href="../index.html" />
 
30
    <link rel="top" title="SQLAlchemy 0.7 Documentation" href="../index.html" />
31
31
        <link rel="up" title="SQLAlchemy ORM" href="index.html" />
32
32
        <link rel="next" title="Mapper Configuration" href="mapper_config.html" />
33
33
        <link rel="prev" title="SQLAlchemy ORM" href="index.html" />
38
38
 
39
39
 
40
40
 
41
 
<h1>SQLAlchemy 0.6.8 Documentation</h1>
 
41
<h1>SQLAlchemy 0.7 Documentation</h1>
42
42
 
43
43
<div id="search">
44
44
Search:
50
50
</div>
51
51
 
52
52
<div class="versionheader">
53
 
    Version: <span class="versionnum">0.6.8</span> Last Updated: 06/05/2011 13:10:26
 
53
    Release: <span class="versionnum">0.7.2</span> | Release Date: July 31, 2011
54
54
</div>
55
55
<div class="clearboth"></div>
56
56
 
72
72
        </ul>
73
73
    </div>
74
74
    <div id="navbanner">
75
 
        <a class="totoc" href="../index.html">SQLAlchemy 0.6.8 Documentation</a>
 
75
        <a class="totoc" href="../index.html">SQLAlchemy 0.7 Documentation</a>
76
76
                » <a href="index.html" title="SQLAlchemy ORM">SQLAlchemy ORM</a>
77
77
        » 
78
78
                Object Relational Tutorial
165
165
</div>
166
166
<div class="section" id="version-check">
167
167
<h2>Version Check<a class="headerlink" href="#version-check" title="Permalink to this headline">¶</a></h2>
168
 
<p>A quick check to verify that we are on at least <strong>version 0.6</strong> of SQLAlchemy:</p>
 
168
<p>A quick check to verify that we are on at least <strong>version 0.7</strong> of SQLAlchemy:</p>
169
169
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">sqlalchemy</span>
170
170
<span class="gp">&gt;&gt;&gt; </span><span class="n">sqlalchemy</span><span class="o">.</span><span class="n">__version__</span> 
171
 
<span class="go">0.6.0</span></pre></div>
 
171
<span class="go">0.7.0</span></pre></div>
172
172
</div>
173
173
</div>
174
174
<div class="section" id="connecting">
857
857
<div class="admonition note">
858
858
<p class="first admonition-title">Note</p>
859
859
<p class="last">The <a class="reference internal" href="relationships.html#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> function has historically
860
 
been known as <a class="reference internal" href="relationships.html#sqlalchemy.orm.relation" title="sqlalchemy.orm.relation"><tt class="xref py py-func docutils literal"><span class="pre">relation()</span></tt></a>, which is the name that&#8217;s
861
 
available in all versions of SQLAlchemy prior to 0.6beta2, including the 0.5
862
 
and 0.4 series. <a class="reference internal" href="relationships.html#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> is only available
863
 
starting with SQLAlchemy 0.6beta2. <a class="reference internal" href="relationships.html#sqlalchemy.orm.relation" title="sqlalchemy.orm.relation"><tt class="xref py py-func docutils literal"><span class="pre">relation()</span></tt></a> will
864
 
remain available in SQLAlchemy for the foreseeable future to enable
865
 
cross-compatibility.</p>
 
860
been known as <a class="reference internal" href="relationships.html#sqlalchemy.orm.relation" title="sqlalchemy.orm.relation"><tt class="xref py py-func docutils literal"><span class="pre">relation()</span></tt></a> in the 0.5 series of
 
861
SQLAlchemy and earlier.</p>
866
862
</div>
867
863
<p>The <a class="reference internal" href="relationships.html#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> function is extremely flexible, and
868
864
could just have easily been defined on the <tt class="docutils literal"><span class="pre">User</span></tt> class:</p>
945
941
COMMIT</div></pre></div>
946
942
</div>
947
943
<p>Querying for Jack, we get just Jack back.  No SQL is yet issued for Jack&#8217;s addresses:</p>
948
 
<div class="highlight-python+sql"><div class="highlight"><pre><a href='#' class='sql_link'>sql</a><span class="o">&gt;&gt;&gt;</span> <span class="n">jack</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">User</span><span class="p">)</span><span class="o">.</span><span class="n">filter_by</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">&#39;jack&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">one</span><span class="p">()</span> 
 
944
<div class="highlight-python+sql"><div class="highlight"><pre><a href='#' class='sql_link'>sql</a><span class="o">&gt;&gt;&gt;</span> <span class="n">jack</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">User</span><span class="p">)</span><span class="o">.</span>\
 
945
<span class="o">...</span> <span class="n">filter_by</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">&#39;jack&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">one</span><span class="p">()</span> 
949
946
<div class='popup_sql'>BEGIN (implicit)
950
 
SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password
 
947
SELECT users.id AS users_id, users.name AS users_name,
 
948
users.fullname AS users_fullname, users.password AS users_password
951
949
FROM users
952
950
WHERE users.name = ?
953
951
('jack',)</div><span class="o">&gt;&gt;&gt;</span> <span class="n">jack</span>
955
953
</div>
956
954
<p>Let&#8217;s look at the <tt class="docutils literal"><span class="pre">addresses</span></tt> collection.  Watch the SQL:</p>
957
955
<div class="highlight-python+sql"><div class="highlight"><pre><a href='#' class='sql_link'>sql</a><span class="o">&gt;&gt;&gt;</span> <span class="n">jack</span><span class="o">.</span><span class="n">addresses</span> 
958
 
<div class='popup_sql'>SELECT addresses.id AS addresses_id, addresses.email_address AS addresses_email_address, addresses.user_id AS addresses_user_id
 
956
<div class='popup_sql'>SELECT addresses.id AS addresses_id, addresses.email_address AS
 
957
addresses_email_address, addresses.user_id AS addresses_user_id
959
958
FROM addresses
960
959
WHERE ? = addresses.user_id ORDER BY addresses.id
961
960
(5,)</div><span class="p">[</span><span class="o">&lt;</span><span class="n">Address</span><span class="p">(</span><span class="s">&#39;jack@google.com&#39;</span><span class="p">)</span><span class="o">&gt;</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">Address</span><span class="p">(</span><span class="s">&#39;j25@yahoo.com&#39;</span><span class="p">)</span><span class="o">&gt;</span><span class="p">]</span></pre></div>
991
990
<a class="reference internal" href="loading.html#sqlalchemy.orm.joinedload" title="sqlalchemy.orm.joinedload"><tt class="xref py py-func docutils literal"><span class="pre">joinedload()</span></tt></a> and its new brother,
992
991
<a class="reference internal" href="loading.html#sqlalchemy.orm.subqueryload" title="sqlalchemy.orm.subqueryload"><tt class="xref py py-func docutils literal"><span class="pre">subqueryload()</span></tt></a>. We&#8217;ll also see another way to &#8220;eagerly&#8221;
993
992
load in the next section.</p>
 
993
<div class="admonition note">
 
994
<p class="first admonition-title">Note</p>
 
995
<p class="last">The join created by <a class="reference internal" href="loading.html#sqlalchemy.orm.joinedload" title="sqlalchemy.orm.joinedload"><tt class="xref py py-func docutils literal"><span class="pre">joinedload()</span></tt></a> is anonymously aliased such that
 
996
it <strong>does not affect the query results</strong>.   An <a class="reference internal" href="query.html#sqlalchemy.orm.query.Query.order_by" title="sqlalchemy.orm.query.Query.order_by"><tt class="xref py py-meth docutils literal"><span class="pre">Query.order_by()</span></tt></a>
 
997
or <a class="reference internal" href="query.html#sqlalchemy.orm.query.Query.filter" title="sqlalchemy.orm.query.Query.filter"><tt class="xref py py-meth docutils literal"><span class="pre">Query.filter()</span></tt></a> call <strong>cannot</strong> reference these aliased
 
998
tables - so-called &#8220;user space&#8221; joins are constructed using
 
999
<a class="reference internal" href="query.html#sqlalchemy.orm.query.Query.join" title="sqlalchemy.orm.query.Query.join"><tt class="xref py py-meth docutils literal"><span class="pre">Query.join()</span></tt></a>.   The rationale for this is that <a class="reference internal" href="loading.html#sqlalchemy.orm.joinedload" title="sqlalchemy.orm.joinedload"><tt class="xref py py-func docutils literal"><span class="pre">joinedload()</span></tt></a> is only
 
1000
applied in order to affect how related objects or collections are loaded
 
1001
as an optimizing detail - it can be added or removed with no impact
 
1002
on actual results.   See the section <a class="reference internal" href="loading.html#zen-of-eager-loading"><em>The Zen of Eager Loading</em></a> for
 
1003
a detailed description of how this is used, including how to use a single
 
1004
explicit JOIN for filtering/ordering and eager loading simultaneously.</p>
 
1005
</div>
994
1006
</div>
995
1007
<div class="section" id="querying-with-joins">
996
 
<h2>Querying with Joins<a class="headerlink" href="#querying-with-joins" title="Permalink to this headline">¶</a></h2>
997
 
<p>While <a class="reference internal" href="loading.html#sqlalchemy.orm.joinedload" title="sqlalchemy.orm.joinedload"><tt class="xref py py-func docutils literal"><span class="pre">joinedload()</span></tt></a> created a JOIN specifically to
 
1008
<span id="ormtutorial-joins"></span><h2>Querying with Joins<a class="headerlink" href="#querying-with-joins" title="Permalink to this headline">¶</a></h2>
 
1009
<p>While <a class="reference internal" href="loading.html#sqlalchemy.orm.joinedload" title="sqlalchemy.orm.joinedload"><tt class="xref py py-func docutils literal"><span class="pre">joinedload()</span></tt></a> created an anonymous, non-accessible JOIN
 
1010
specifically to
998
1011
populate a collection, we can also work explicitly with joins in many ways.
999
1012
For example, to construct a simple inner join between <tt class="docutils literal"><span class="pre">User</span></tt> and
1000
1013
<tt class="docutils literal"><span class="pre">Address</span></tt>, we can just <a class="reference internal" href="query.html#sqlalchemy.orm.query.Query.filter" title="sqlalchemy.orm.query.Query.filter"><tt class="xref py py-meth docutils literal"><span class="pre">filter()</span></tt></a> their
1019
1032
WHERE addresses.email_address = ?
1020
1033
('jack@google.com',)</div><span class="p">[</span><span class="o">&lt;</span><span class="n">User</span><span class="p">(</span><span class="s">&#39;jack&#39;</span><span class="p">,</span><span class="s">&#39;Jack Bean&#39;</span><span class="p">,</span> <span class="s">&#39;gjffdd&#39;</span><span class="p">)</span><span class="o">&gt;</span><span class="p">]</span></pre></div>
1021
1034
</div>
1022
 
<p><a class="reference internal" href="query.html#sqlalchemy.orm.query.Query.join" title="sqlalchemy.orm.query.Query.join"><tt class="xref py py-meth docutils literal"><span class="pre">join()</span></tt></a> knows how to join between <tt class="docutils literal"><span class="pre">User</span></tt> and <tt class="docutils literal"><span class="pre">Address</span></tt> because there&#8217;s only one foreign key between them.  If there were no foreign keys, or several, <a class="reference internal" href="query.html#sqlalchemy.orm.query.Query.join" title="sqlalchemy.orm.query.Query.join"><tt class="xref py py-meth docutils literal"><span class="pre">join()</span></tt></a> works better when one of the following forms are used:</p>
1023
 
<div class="highlight-python"><div class="highlight"><pre><span class="n">query</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">Address</span><span class="p">,</span> <span class="n">User</span><span class="o">.</span><span class="n">id</span><span class="o">==</span><span class="n">Address</span><span class="o">.</span><span class="n">user_id</span><span class="p">))</span>  <span class="c"># explicit condition (note the tuple)</span>
 
1035
<p><a class="reference internal" href="query.html#sqlalchemy.orm.query.Query.join" title="sqlalchemy.orm.query.Query.join"><tt class="xref py py-meth docutils literal"><span class="pre">join()</span></tt></a> knows how to join between <tt class="docutils literal"><span class="pre">User</span></tt>
 
1036
and <tt class="docutils literal"><span class="pre">Address</span></tt> because there&#8217;s only one foreign key between them. If there
 
1037
were no foreign keys, or several, <a class="reference internal" href="query.html#sqlalchemy.orm.query.Query.join" title="sqlalchemy.orm.query.Query.join"><tt class="xref py py-meth docutils literal"><span class="pre">join()</span></tt></a>
 
1038
works better when one of the following forms are used:</p>
 
1039
<div class="highlight-python"><div class="highlight"><pre><span class="n">query</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">Address</span><span class="p">,</span> <span class="n">User</span><span class="o">.</span><span class="n">id</span><span class="o">==</span><span class="n">Address</span><span class="o">.</span><span class="n">user_id</span><span class="p">)</span>    <span class="c"># explicit condition</span>
1024
1040
<span class="n">query</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">addresses</span><span class="p">)</span>                       <span class="c"># specify relationship from left to right</span>
1025
 
<span class="n">query</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">Address</span><span class="p">,</span> <span class="n">User</span><span class="o">.</span><span class="n">addresses</span><span class="p">))</span>            <span class="c"># same, with explicit target</span>
 
1041
<span class="n">query</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">Address</span><span class="p">,</span> <span class="n">User</span><span class="o">.</span><span class="n">addresses</span><span class="p">)</span>              <span class="c"># same, with explicit target</span>
1026
1042
<span class="n">query</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s">&#39;addresses&#39;</span><span class="p">)</span>                          <span class="c"># same, using a string</span></pre></div>
1027
1043
</div>
1028
 
<p>Note that when <a class="reference internal" href="query.html#sqlalchemy.orm.query.Query.join" title="sqlalchemy.orm.query.Query.join"><tt class="xref py py-meth docutils literal"><span class="pre">join()</span></tt></a> is called with an explicit target as well as an ON clause, we use a tuple as the argument.  This is so that multiple joins can be chained together, as in:</p>
 
1044
<p>As you would expect, the same idea is used for &#8220;outer&#8221; joins, using the
 
1045
<a class="reference internal" href="query.html#sqlalchemy.orm.query.Query.outerjoin" title="sqlalchemy.orm.query.Query.outerjoin"><tt class="xref py py-meth docutils literal"><span class="pre">outerjoin()</span></tt></a> function:</p>
 
1046
<div class="highlight-python"><div class="highlight"><pre><span class="n">query</span><span class="o">.</span><span class="n">outerjoin</span><span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">addresses</span><span class="p">)</span>   <span class="c"># LEFT OUTER JOIN</span></pre></div>
 
1047
</div>
 
1048
<p>Note that when <a class="reference internal" href="query.html#sqlalchemy.orm.query.Query.join" title="sqlalchemy.orm.query.Query.join"><tt class="xref py py-meth docutils literal"><span class="pre">join()</span></tt></a> is called with an
 
1049
explicit target as well as an ON clause, we use a tuple as the argument. This
 
1050
is so that multiple joins can be chained together, as in:</p>
1029
1051
<div class="highlight-python"><div class="highlight"><pre><span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Foo</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
1030
1052
                        <span class="n">Foo</span><span class="o">.</span><span class="n">bars</span><span class="p">,</span>
1031
1053
                        <span class="p">(</span><span class="n">Bat</span><span class="p">,</span> <span class="n">bar</span><span class="o">.</span><span class="n">bats</span><span class="p">),</span>
1098
1120
<span class="o">&gt;&gt;&gt;</span> <span class="n">adalias2</span> <span class="o">=</span> <span class="n">aliased</span><span class="p">(</span><span class="n">Address</span><span class="p">)</span>
1099
1121
<a href='#' class='sql_link'>sql</a><span class="o">&gt;&gt;&gt;</span> <span class="k">for</span> <span class="n">username</span><span class="p">,</span> <span class="n">email1</span><span class="p">,</span> <span class="n">email2</span> <span class="ow">in</span> \
1100
1122
<span class="o">...</span>     <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">adalias1</span><span class="o">.</span><span class="n">email_address</span><span class="p">,</span> <span class="n">adalias2</span><span class="o">.</span><span class="n">email_address</span><span class="p">)</span><span class="o">.</span>\
1101
 
<span class="o">...</span>     <span class="n">join</span><span class="p">((</span><span class="n">adalias1</span><span class="p">,</span> <span class="n">User</span><span class="o">.</span><span class="n">addresses</span><span class="p">),</span> <span class="p">(</span><span class="n">adalias2</span><span class="p">,</span> <span class="n">User</span><span class="o">.</span><span class="n">addresses</span><span class="p">))</span><span class="o">.</span>\
 
1123
<span class="o">...</span>     <span class="n">join</span><span class="p">(</span><span class="n">adalias1</span><span class="p">,</span> <span class="n">User</span><span class="o">.</span><span class="n">addresses</span><span class="p">)</span><span class="o">.</span>\
 
1124
<span class="o">...</span>     <span class="n">join</span><span class="p">(</span><span class="n">adalias2</span><span class="p">,</span> <span class="n">User</span><span class="o">.</span><span class="n">addresses</span><span class="p">)</span><span class="o">.</span>\
1102
1125
<span class="o">...</span>     <span class="nb">filter</span><span class="p">(</span><span class="n">adalias1</span><span class="o">.</span><span class="n">email_address</span><span class="o">==</span><span class="s">&#39;jack@google.com&#39;</span><span class="p">)</span><span class="o">.</span>\
1103
1126
<span class="o">...</span>     <span class="nb">filter</span><span class="p">(</span><span class="n">adalias2</span><span class="o">.</span><span class="n">email_address</span><span class="o">==</span><span class="s">&#39;j25@yahoo.com&#39;</span><span class="p">):</span>
1104
1127
<span class="o">...</span>     <span class="k">print</span> <span class="n">username</span><span class="p">,</span> <span class="n">email1</span><span class="p">,</span> <span class="n">email2</span>      
1139
1162
<tt class="docutils literal"><span class="pre">users</span></tt> at the start of this tutorial. The columns on the statement are
1140
1163
accessible through an attribute called <tt class="docutils literal"><span class="pre">c</span></tt>:</p>
1141
1164
<div class="highlight-python+sql"><div class="highlight"><pre><a href='#' class='sql_link'>sql</a><span class="o">&gt;&gt;&gt;</span> <span class="k">for</span> <span class="n">u</span><span class="p">,</span> <span class="n">count</span> <span class="ow">in</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">User</span><span class="p">,</span> <span class="n">stmt</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">address_count</span><span class="p">)</span><span class="o">.</span>\
1142
 
<span class="o">...</span>     <span class="n">outerjoin</span><span class="p">((</span><span class="n">stmt</span><span class="p">,</span> <span class="n">User</span><span class="o">.</span><span class="n">id</span><span class="o">==</span><span class="n">stmt</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">user_id</span><span class="p">))</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">id</span><span class="p">):</span> 
 
1165
<span class="o">...</span>     <span class="n">outerjoin</span><span class="p">(</span><span class="n">stmt</span><span class="p">,</span> <span class="n">User</span><span class="o">.</span><span class="n">id</span><span class="o">==</span><span class="n">stmt</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">user_id</span><span class="p">)</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">id</span><span class="p">):</span> 
1143
1166
<span class="o">...</span>     <span class="k">print</span> <span class="n">u</span><span class="p">,</span> <span class="n">count</span>
1144
1167
<div class='popup_sql'>SELECT users.id AS users_id, users.name AS users_name,
1145
1168
users.fullname AS users_fullname, users.password AS users_password,
1161
1184
to associate an &#8220;alias&#8221; of a mapped class to a subquery:</p>
1162
1185
<div class="highlight-python+sql"><div class="highlight"><pre><a href='#' class='sql_link'>sql</a><span class="o">&gt;&gt;&gt;</span> <span class="n">stmt</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Address</span><span class="p">)</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">Address</span><span class="o">.</span><span class="n">email_address</span> <span class="o">!=</span> <span class="s">&#39;j25@yahoo.com&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">subquery</span><span class="p">()</span>
1163
1186
<span class="o">&gt;&gt;&gt;</span> <span class="n">adalias</span> <span class="o">=</span> <span class="n">aliased</span><span class="p">(</span><span class="n">Address</span><span class="p">,</span> <span class="n">stmt</span><span class="p">)</span>
1164
 
<span class="o">&gt;&gt;&gt;</span> <span class="k">for</span> <span class="n">user</span><span class="p">,</span> <span class="n">address</span> <span class="ow">in</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">User</span><span class="p">,</span> <span class="n">adalias</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="n">adalias</span><span class="p">,</span> <span class="n">User</span><span class="o">.</span><span class="n">addresses</span><span class="p">)):</span> 
 
1187
<span class="o">&gt;&gt;&gt;</span> <span class="k">for</span> <span class="n">user</span><span class="p">,</span> <span class="n">address</span> <span class="ow">in</span> <span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">User</span><span class="p">,</span> <span class="n">adalias</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">adalias</span><span class="p">,</span> <span class="n">User</span><span class="o">.</span><span class="n">addresses</span><span class="p">):</span> 
1165
1188
<span class="o">...</span>     <span class="k">print</span> <span class="n">user</span><span class="p">,</span> <span class="n">address</span>
1166
1189
<div class='popup_sql'>SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname,
1167
1190
users.password AS users_password, anon_1.id AS anon_1_id,
1226
1249
</div>
1227
1250
<div class="section" id="common-relationship-operators">
1228
1251
<h3>Common Relationship Operators<a class="headerlink" href="#common-relationship-operators" title="Permalink to this headline">¶</a></h3>
1229
 
<p>Here&#8217;s all the operators which build on relationships:</p>
 
1252
<p>Here&#8217;s all the operators which build on relationships - each one
 
1253
is linked to its API documentation which includes full details on usage
 
1254
and behavior:</p>
1230
1255
<ul>
1231
 
<li><p class="first">equals (used for many-to-one):</p>
 
1256
<li><p class="first"><a class="reference internal" href="internals.html#sqlalchemy.orm.properties.RelationshipProperty.Comparator.__eq__" title="sqlalchemy.orm.properties.RelationshipProperty.Comparator.__eq__"><tt class="xref py py-meth docutils literal"><span class="pre">__eq__()</span></tt></a> (many-to-one &#8220;equals&#8221; comparison):</p>
1232
1257
<div class="highlight-python"><div class="highlight"><pre><span class="n">query</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">Address</span><span class="o">.</span><span class="n">user</span> <span class="o">==</span> <span class="n">someuser</span><span class="p">)</span></pre></div>
1233
1258
</div>
1234
1259
</li>
1235
 
<li><p class="first">not equals (used for many-to-one):</p>
 
1260
<li><p class="first"><a class="reference internal" href="internals.html#sqlalchemy.orm.properties.RelationshipProperty.Comparator.__ne__" title="sqlalchemy.orm.properties.RelationshipProperty.Comparator.__ne__"><tt class="xref py py-meth docutils literal"><span class="pre">__ne__()</span></tt></a> (many-to-one &#8220;not equals&#8221; comparison):</p>
1236
1261
<div class="highlight-python"><div class="highlight"><pre><span class="n">query</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">Address</span><span class="o">.</span><span class="n">user</span> <span class="o">!=</span> <span class="n">someuser</span><span class="p">)</span></pre></div>
1237
1262
</div>
1238
1263
</li>
1239
 
<li><p class="first">IS NULL (used for many-to-one):</p>
 
1264
<li><p class="first">IS NULL (many-to-one comparison, also uses <a class="reference internal" href="internals.html#sqlalchemy.orm.properties.RelationshipProperty.Comparator.__eq__" title="sqlalchemy.orm.properties.RelationshipProperty.Comparator.__eq__"><tt class="xref py py-meth docutils literal"><span class="pre">__eq__()</span></tt></a>):</p>
1240
1265
<div class="highlight-python"><div class="highlight"><pre><span class="n">query</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">Address</span><span class="o">.</span><span class="n">user</span> <span class="o">==</span> <span class="bp">None</span><span class="p">)</span></pre></div>
1241
1266
</div>
1242
1267
</li>
1243
 
<li><p class="first">contains (used for one-to-many and many-to-many collections):</p>
 
1268
<li><p class="first"><a class="reference internal" href="internals.html#sqlalchemy.orm.properties.RelationshipProperty.Comparator.contains" title="sqlalchemy.orm.properties.RelationshipProperty.Comparator.contains"><tt class="xref py py-meth docutils literal"><span class="pre">contains()</span></tt></a> (used for one-to-many collections):</p>
1244
1269
<div class="highlight-python"><div class="highlight"><pre><span class="n">query</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">addresses</span><span class="o">.</span><span class="n">contains</span><span class="p">(</span><span class="n">someaddress</span><span class="p">))</span></pre></div>
1245
1270
</div>
1246
1271
</li>
1247
 
<li><p class="first">any (used for one-to-many and many-to-many collections):</p>
 
1272
<li><p class="first"><a class="reference internal" href="internals.html#sqlalchemy.orm.properties.RelationshipProperty.Comparator.any" title="sqlalchemy.orm.properties.RelationshipProperty.Comparator.any"><tt class="xref py py-meth docutils literal"><span class="pre">any()</span></tt></a> (used for collections):</p>
1248
1273
<div class="highlight-python"><div class="highlight"><pre><span class="n">query</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">addresses</span><span class="o">.</span><span class="n">any</span><span class="p">(</span><span class="n">Address</span><span class="o">.</span><span class="n">email_address</span> <span class="o">==</span> <span class="s">&#39;bar&#39;</span><span class="p">))</span>
1249
1274
 
1250
1275
<span class="c"># also takes keyword arguments:</span>
1251
1276
<span class="n">query</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">addresses</span><span class="o">.</span><span class="n">any</span><span class="p">(</span><span class="n">email_address</span><span class="o">=</span><span class="s">&#39;bar&#39;</span><span class="p">))</span></pre></div>
1252
1277
</div>
1253
1278
</li>
1254
 
<li><p class="first">has (used for many-to-one):</p>
 
1279
<li><p class="first"><a class="reference internal" href="internals.html#sqlalchemy.orm.properties.RelationshipProperty.Comparator.has" title="sqlalchemy.orm.properties.RelationshipProperty.Comparator.has"><tt class="xref py py-meth docutils literal"><span class="pre">has()</span></tt></a> (used for scalar references):</p>
1255
1280
<div class="highlight-python"><div class="highlight"><pre><span class="n">query</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">Address</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">has</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">&#39;ed&#39;</span><span class="p">))</span></pre></div>
1256
1281
</div>
1257
1282
</li>
1258
 
<li><p class="first">with_parent (used for any relationship):</p>
 
1283
<li><p class="first"><a class="reference internal" href="query.html#sqlalchemy.orm.query.Query.with_parent" title="sqlalchemy.orm.query.Query.with_parent"><tt class="xref py py-meth docutils literal"><span class="pre">Query.with_parent()</span></tt></a> (used for any relationship):</p>
1259
1284
<div class="highlight-python"><div class="highlight"><pre><span class="n">session</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">Address</span><span class="p">)</span><span class="o">.</span><span class="n">with_parent</span><span class="p">(</span><span class="n">someuser</span><span class="p">,</span> <span class="s">&#39;addresses&#39;</span><span class="p">)</span></pre></div>
1260
1285
</div>
1261
1286
</li>
1325
1350
<span class="o">&gt;&gt;&gt;</span> <span class="n">mapper</span><span class="p">(</span><span class="n">Address</span><span class="p">,</span> <span class="n">addresses_table</span><span class="p">)</span> 
1326
1351
<span class="o">&lt;</span><span class="n">Mapper</span> <span class="n">at</span> <span class="mi">0</span><span class="n">x</span><span class="o">...</span><span class="p">;</span> <span class="n">Address</span><span class="o">&gt;</span></pre></div>
1327
1352
</div>
1328
 
<p>Now when we load Jack (below using <tt class="xref py py-meth docutils literal"><span class="pre">get()</span></tt>, which loads by primary key),
 
1353
<p>Now when we load Jack (below using <a class="reference internal" href="query.html#sqlalchemy.orm.query.Query.get" title="sqlalchemy.orm.query.Query.get"><tt class="xref py py-meth docutils literal"><span class="pre">get()</span></tt></a>, which loads by primary key),
1329
1354
removing an address from his <tt class="docutils literal"><span class="pre">addresses</span></tt> collection will result in that
1330
1355
<tt class="docutils literal"><span class="pre">Address</span></tt> being deleted:</p>
1331
1356
<div class="highlight-python+sql"><div class="highlight"><pre><span class="c"># load Jack by primary key</span>