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

« back to all changes in this revision

Viewing changes to doc/orm/relationships.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
                Relationship Configuration
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="Collection Configuration and Techniques" href="collections.html" />
33
33
        <link rel="prev" title="Mapper Configuration" href="mapper_config.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
                Relationship Configuration
98
98
<li><a class="reference internal" href="#configuring-eager-loading">Configuring Eager Loading</a></li>
99
99
</ul>
100
100
</li>
 
101
<li><a class="reference internal" href="#linking-relationships-with-backref">Linking relationships with Backref</a><ul>
 
102
<li><a class="reference internal" href="#backref-arguments">Backref Arguments</a></li>
 
103
<li><a class="reference internal" href="#one-way-backrefs">One Way Backrefs</a></li>
 
104
</ul>
 
105
</li>
101
106
<li><a class="reference internal" href="#specifying-alternate-join-conditions-to-relationship">Specifying Alternate Join Conditions to relationship()</a><ul>
 
107
<li><a class="reference internal" href="#self-referential-many-to-many-relationship">Self-Referential Many-to-Many Relationship</a></li>
102
108
<li><a class="reference internal" href="#specifying-foreign-keys">Specifying Foreign Keys</a></li>
103
109
<li><a class="reference internal" href="#building-query-enabled-properties">Building Query-Enabled Properties</a></li>
104
110
<li><a class="reference internal" href="#multiple-relationships-against-the-same-parent-child">Multiple Relationships against the Same Parent/Child</a></li>
106
112
</li>
107
113
<li><a class="reference internal" href="#rows-that-point-to-themselves-mutually-dependent-rows">Rows that point to themselves / Mutually Dependent Rows</a></li>
108
114
<li><a class="reference internal" href="#mutable-primary-keys-update-cascades">Mutable Primary Keys / Update Cascades</a></li>
109
 
<li><a class="reference internal" href="#the-relationship-api">The <tt class="docutils literal"><span class="pre">relationship()</span></tt> API</a></li>
 
115
<li><a class="reference internal" href="#relationships-api">Relationships API</a></li>
110
116
</ul>
111
117
</li>
112
118
</ul>
581
587
</div>
582
588
</div>
583
589
</div>
 
590
<div class="section" id="linking-relationships-with-backref">
 
591
<h2>Linking relationships with Backref<a class="headerlink" href="#linking-relationships-with-backref" title="Permalink to this headline">¶</a></h2>
 
592
<p>The <tt class="docutils literal"><span class="pre">backref</span></tt> keyword argument was first introduced in <a class="reference internal" href="tutorial.html"><em>Object Relational Tutorial</em></a>, and has been
 
593
mentioned throughout many of the examples here.   What does it actually do ?   Let&#8217;s start
 
594
with the canonical <tt class="docutils literal"><span class="pre">User</span></tt> and <tt class="docutils literal"><span class="pre">Address</span></tt> scenario:</p>
 
595
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">,</span> <span class="n">String</span><span class="p">,</span> <span class="n">Column</span>
 
596
<span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span> <span class="n">declarative_base</span>
 
597
<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="n">relationship</span>
 
598
 
 
599
<span class="n">Base</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">()</span>
 
600
 
 
601
<span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
 
602
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;user&#39;</span>
 
603
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
 
604
    <span class="n">name</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">)</span>
 
605
 
 
606
    <span class="n">addresses</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="s">&quot;Address&quot;</span><span class="p">,</span> <span class="n">backref</span><span class="o">=</span><span class="s">&quot;user&quot;</span><span class="p">)</span>
 
607
 
 
608
<span class="k">class</span> <span class="nc">Address</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
 
609
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;address&#39;</span>
 
610
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
 
611
    <span class="n">email</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">)</span>
 
612
    <span class="n">user_id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s">&#39;user.id&#39;</span><span class="p">))</span></pre></div>
 
613
</div>
 
614
<p>The above configuration establishes a collection of <tt class="docutils literal"><span class="pre">Address</span></tt> objects on <tt class="docutils literal"><span class="pre">User</span></tt> called
 
615
<tt class="docutils literal"><span class="pre">User.addresses</span></tt>.   It also establishes a <tt class="docutils literal"><span class="pre">.user</span></tt> attribute on <tt class="docutils literal"><span class="pre">Address</span></tt> which will
 
616
refer to the parent <tt class="docutils literal"><span class="pre">User</span></tt> object.</p>
 
617
<p>In fact, the <tt class="docutils literal"><span class="pre">backref</span></tt> keyword is only a common shortcut for placing a second
 
618
<tt class="docutils literal"><span class="pre">relationship</span></tt> onto the <tt class="docutils literal"><span class="pre">Address</span></tt> mapping, including the establishment
 
619
of an event listener on both sides which will mirror attribute operations
 
620
in both directions.   The above configuration is equivalent to:</p>
 
621
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">,</span> <span class="n">String</span><span class="p">,</span> <span class="n">Column</span>
 
622
<span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span> <span class="n">declarative_base</span>
 
623
<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="n">relationship</span>
 
624
 
 
625
<span class="n">Base</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">()</span>
 
626
 
 
627
<span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
 
628
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;user&#39;</span>
 
629
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
 
630
    <span class="n">name</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">)</span>
 
631
 
 
632
    <span class="n">addresses</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="s">&quot;Address&quot;</span><span class="p">,</span> <span class="n">back_populates</span><span class="o">=</span><span class="s">&quot;user&quot;</span><span class="p">)</span>
 
633
 
 
634
<span class="k">class</span> <span class="nc">Address</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
 
635
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;address&#39;</span>
 
636
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
 
637
    <span class="n">email</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">)</span>
 
638
    <span class="n">user_id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s">&#39;user.id&#39;</span><span class="p">))</span>
 
639
 
 
640
    <span class="n">user</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="s">&quot;User&quot;</span><span class="p">,</span> <span class="n">back_populates</span><span class="o">=</span><span class="s">&quot;addresses&quot;</span><span class="p">)</span></pre></div>
 
641
</div>
 
642
<p>Above, we add a <tt class="docutils literal"><span class="pre">.user</span></tt> relationship to <tt class="docutils literal"><span class="pre">Address</span></tt> explicitly.  On
 
643
both relationships, the <tt class="docutils literal"><span class="pre">back_populates</span></tt> directive tells each relationship
 
644
about the other one, indicating that they should establish &#8220;bi-directional&#8221;
 
645
behavior between each other.   The primary effect of this configuration
 
646
is that the relationship adds event handlers to both attributes
 
647
which have the behavior of &#8220;when an append or set event occurs here, set ourselves
 
648
onto the incoming attribute using this particular attribute name&#8221;.
 
649
The behavior is illustrated as follows.   Start with a <tt class="docutils literal"><span class="pre">User</span></tt> and an <tt class="docutils literal"><span class="pre">Address</span></tt>
 
650
instance.  The <tt class="docutils literal"><span class="pre">.addresses</span></tt> collection is empty, and the <tt class="docutils literal"><span class="pre">.user</span></tt> attribute
 
651
is <tt class="xref docutils literal"><span class="pre">None</span></tt>:</p>
 
652
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">u1</span> <span class="o">=</span> <span class="n">User</span><span class="p">()</span>
 
653
<span class="gp">&gt;&gt;&gt; </span><span class="n">a1</span> <span class="o">=</span> <span class="n">Address</span><span class="p">()</span>
 
654
<span class="gp">&gt;&gt;&gt; </span><span class="n">u1</span><span class="o">.</span><span class="n">addresses</span>
 
655
<span class="go">[]</span>
 
656
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">a1</span><span class="o">.</span><span class="n">user</span>
 
657
<span class="go">None</span></pre></div>
 
658
</div>
 
659
<p>However, once the <tt class="docutils literal"><span class="pre">Address</span></tt> is appended to the <tt class="docutils literal"><span class="pre">u1.addresses</span></tt> collection,
 
660
both the collection and the scalar attribute have been populated:</p>
 
661
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">u1</span><span class="o">.</span><span class="n">addresses</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">a1</span><span class="p">)</span>
 
662
<span class="gp">&gt;&gt;&gt; </span><span class="n">u1</span><span class="o">.</span><span class="n">addresses</span>
 
663
<span class="go">[&lt;__main__.Address object at 0x12a6ed0&gt;]</span>
 
664
<span class="gp">&gt;&gt;&gt; </span><span class="n">a1</span><span class="o">.</span><span class="n">user</span>
 
665
<span class="go">&lt;__main__.User object at 0x12a6590&gt;</span></pre></div>
 
666
</div>
 
667
<p>This behavior of course works in reverse for removal operations as well, as well
 
668
as for equivalent operations on both sides.   Such as
 
669
when <tt class="docutils literal"><span class="pre">.user</span></tt> is set again to <tt class="xref docutils literal"><span class="pre">None</span></tt>, the <tt class="docutils literal"><span class="pre">Address</span></tt> object is removed
 
670
from the reverse collection:</p>
 
671
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">a1</span><span class="o">.</span><span class="n">user</span> <span class="o">=</span> <span class="bp">None</span>
 
672
<span class="gp">&gt;&gt;&gt; </span><span class="n">u1</span><span class="o">.</span><span class="n">addresses</span>
 
673
<span class="go">[]</span></pre></div>
 
674
</div>
 
675
<p>The manipulation of the <tt class="docutils literal"><span class="pre">.addresses</span></tt> collection and the <tt class="docutils literal"><span class="pre">.user</span></tt> attribute
 
676
occurs entirely in Python without any interaction with the SQL database.
 
677
Without this behavior, the proper state would be apparent on both sides once the
 
678
data has been flushed to the database, and later reloaded after a commit or
 
679
expiration operation occurs.  The <tt class="docutils literal"><span class="pre">backref</span></tt>/<tt class="docutils literal"><span class="pre">back_populates</span></tt> behavior has the advantage
 
680
that common bidirectional operations can reflect the correct state without requiring
 
681
a database round trip.</p>
 
682
<p>Remember, when the <tt class="docutils literal"><span class="pre">backref</span></tt> keyword is used on a single relationship, it&#8217;s
 
683
exactly the same as if the above two relationships were created individually
 
684
using <tt class="docutils literal"><span class="pre">back_populates</span></tt> on each.</p>
 
685
<div class="section" id="backref-arguments">
 
686
<h3>Backref Arguments<a class="headerlink" href="#backref-arguments" title="Permalink to this headline">¶</a></h3>
 
687
<p>We&#8217;ve established that the <tt class="docutils literal"><span class="pre">backref</span></tt> keyword is merely a shortcut for building
 
688
two individual <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> constructs that refer to each other.  Part of
 
689
the behavior of this shortcut is that certain configurational arguments applied to
 
690
the <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a>
 
691
will also be applied to the other direction - namely those arguments that describe
 
692
the relationship at a schema level, and are unlikely to be different in the reverse
 
693
direction.  The usual case
 
694
here is a many-to-many <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> that has a <tt class="docutils literal"><span class="pre">secondary</span></tt> argument,
 
695
or a one-to-many or many-to-one which has a <tt class="docutils literal"><span class="pre">primaryjoin</span></tt> argument (the
 
696
<tt class="docutils literal"><span class="pre">primaryjoin</span></tt> argument is discussed in <a class="reference internal" href="#relationship-primaryjoin"><em>Specifying Alternate Join Conditions to relationship()</em></a>).  Such
 
697
as if we limited the list of <tt class="docutils literal"><span class="pre">Address</span></tt> objects to those which start with &#8220;tony&#8221;:</p>
 
698
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">,</span> <span class="n">String</span><span class="p">,</span> <span class="n">Column</span>
 
699
<span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span> <span class="n">declarative_base</span>
 
700
<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="n">relationship</span>
 
701
 
 
702
<span class="n">Base</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">()</span>
 
703
 
 
704
<span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
 
705
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;user&#39;</span>
 
706
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
 
707
    <span class="n">name</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">)</span>
 
708
 
 
709
    <span class="n">addresses</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="s">&quot;Address&quot;</span><span class="p">,</span>
 
710
                    <span class="n">primaryjoin</span><span class="o">=</span><span class="s">&quot;and_(User.id==Address.user_id, &quot;</span>
 
711
                        <span class="s">&quot;Address.email.startswith(&#39;tony&#39;))&quot;</span><span class="p">,</span>
 
712
                    <span class="n">backref</span><span class="o">=</span><span class="s">&quot;user&quot;</span><span class="p">)</span>
 
713
 
 
714
<span class="k">class</span> <span class="nc">Address</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
 
715
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;address&#39;</span>
 
716
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
 
717
    <span class="n">email</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">)</span>
 
718
    <span class="n">user_id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s">&#39;user.id&#39;</span><span class="p">))</span></pre></div>
 
719
</div>
 
720
<p>We can observe, by inspecting the resulting property, that both sides
 
721
of the relationship have this join condition applied:</p>
 
722
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">User</span><span class="o">.</span><span class="n">addresses</span><span class="o">.</span><span class="n">property</span><span class="o">.</span><span class="n">primaryjoin</span>
 
723
<span class="go">&quot;user&quot;.id = address.user_id AND address.email LIKE :email_1 || &#39;%%&#39;</span>
 
724
<span class="go">&gt;&gt;&gt;</span>
 
725
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">Address</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">property</span><span class="o">.</span><span class="n">primaryjoin</span>
 
726
<span class="go">&quot;user&quot;.id = address.user_id AND address.email LIKE :email_1 || &#39;%%&#39;</span>
 
727
<span class="go">&gt;&gt;&gt;</span></pre></div>
 
728
</div>
 
729
<p>This reuse of arguments should pretty much do the &#8220;right thing&#8221; - it uses
 
730
only arguments that are applicable, and in the case of a many-to-many
 
731
relationship, will reverse the usage of <tt class="docutils literal"><span class="pre">primaryjoin</span></tt> and <tt class="docutils literal"><span class="pre">secondaryjoin</span></tt>
 
732
to correspond to the other direction (see the example in <a class="reference internal" href="#self-referential-many-to-many"><em>Self-Referential Many-to-Many Relationship</em></a>
 
733
for this).</p>
 
734
<p>It&#8217;s very often the case however that we&#8217;d like to specify arguments that
 
735
are specific to just the side where we happened to place the &#8220;backref&#8221;.
 
736
This includes <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> arguments like <tt class="docutils literal"><span class="pre">lazy</span></tt>, <tt class="docutils literal"><span class="pre">remote_side</span></tt>,
 
737
<tt class="docutils literal"><span class="pre">cascade</span></tt> and <tt class="docutils literal"><span class="pre">cascade_backrefs</span></tt>.   For this case we use the <a class="reference internal" href="#sqlalchemy.orm.backref" title="sqlalchemy.orm.backref"><tt class="xref py py-func docutils literal"><span class="pre">backref()</span></tt></a>
 
738
function in place of a string:</p>
 
739
<div class="highlight-python"><div class="highlight"><pre><span class="c"># &lt;other imports&gt;</span>
 
740
<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="n">backref</span>
 
741
 
 
742
<span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
 
743
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;user&#39;</span>
 
744
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
 
745
    <span class="n">name</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">)</span>
 
746
 
 
747
    <span class="n">addresses</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="s">&quot;Address&quot;</span><span class="p">,</span>
 
748
                    <span class="n">backref</span><span class="o">=</span><span class="n">backref</span><span class="p">(</span><span class="s">&quot;user&quot;</span><span class="p">,</span> <span class="n">lazy</span><span class="o">=</span><span class="s">&quot;joined&quot;</span><span class="p">))</span></pre></div>
 
749
</div>
 
750
<p>Where above, we placed a <tt class="docutils literal"><span class="pre">lazy=&quot;joined&quot;</span></tt> directive only on the <tt class="docutils literal"><span class="pre">Address.user</span></tt>
 
751
side, indicating that when a query against <tt class="docutils literal"><span class="pre">Address</span></tt> is made, a join to the <tt class="docutils literal"><span class="pre">User</span></tt>
 
752
entity should be made automatically which will populate the <tt class="docutils literal"><span class="pre">.user</span></tt> attribute of each
 
753
returned <tt class="docutils literal"><span class="pre">Address</span></tt>.   The <a class="reference internal" href="#sqlalchemy.orm.backref" title="sqlalchemy.orm.backref"><tt class="xref py py-func docutils literal"><span class="pre">backref()</span></tt></a> function formatted the arguments we gave
 
754
it into a form that is interpreted by the receiving <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> as additional
 
755
arguments to be applied to the new relationship it creates.</p>
 
756
</div>
 
757
<div class="section" id="one-way-backrefs">
 
758
<h3>One Way Backrefs<a class="headerlink" href="#one-way-backrefs" title="Permalink to this headline">¶</a></h3>
 
759
<p>An unusual case is that of the &#8220;one way backref&#8221;.   This is where the &#8220;back-populating&#8221;
 
760
behavior of the backref is only desirable in one direction. An example of this
 
761
is a collection which contains a filtering <tt class="docutils literal"><span class="pre">primaryjoin</span></tt> condition.   We&#8217;d like to append
 
762
items to this collection as needed, and have them populate the &#8220;parent&#8221; object on the
 
763
incoming object. However, we&#8217;d also like to have items that are not part of the collection,
 
764
but still have the same &#8220;parent&#8221; association - these items should never be in the
 
765
collection.</p>
 
766
<p>Taking our previous example, where we established a <tt class="docutils literal"><span class="pre">primaryjoin</span></tt> that limited the
 
767
collection only to <tt class="docutils literal"><span class="pre">Address</span></tt> objects whose email address started with the word <tt class="docutils literal"><span class="pre">tony</span></tt>,
 
768
the usual backref behavior is that all items populate in both directions.   We wouldn&#8217;t
 
769
want this behavior for a case like the following:</p>
 
770
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">u1</span> <span class="o">=</span> <span class="n">User</span><span class="p">()</span>
 
771
<span class="gp">&gt;&gt;&gt; </span><span class="n">a1</span> <span class="o">=</span> <span class="n">Address</span><span class="p">(</span><span class="n">email</span><span class="o">=</span><span class="s">&#39;mary&#39;</span><span class="p">)</span>
 
772
<span class="gp">&gt;&gt;&gt; </span><span class="n">a1</span><span class="o">.</span><span class="n">user</span> <span class="o">=</span> <span class="n">u1</span>
 
773
<span class="gp">&gt;&gt;&gt; </span><span class="n">u1</span><span class="o">.</span><span class="n">addresses</span>
 
774
<span class="go">[&lt;__main__.Address object at 0x1411910&gt;]</span></pre></div>
 
775
</div>
 
776
<p>Above, the <tt class="docutils literal"><span class="pre">Address</span></tt> object that doesn&#8217;t match the criterion of &#8220;starts with &#8216;tony&#8217;&#8221;
 
777
is present in the <tt class="docutils literal"><span class="pre">addresses</span></tt> collection of <tt class="docutils literal"><span class="pre">u1</span></tt>.   After these objects are flushed,
 
778
the transaction committed and their attributes expired for a re-load, the <tt class="docutils literal"><span class="pre">addresses</span></tt>
 
779
collection will hit the database on next access and no longer have this <tt class="docutils literal"><span class="pre">Address</span></tt> object
 
780
present, due to the filtering condition.   But we can do away with this unwanted side
 
781
of the &#8220;backref&#8221; behavior on the Python side by using two separate <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> constructs,
 
782
placing <tt class="docutils literal"><span class="pre">back_populates</span></tt> only on one side:</p>
 
783
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">,</span> <span class="n">String</span><span class="p">,</span> <span class="n">Column</span>
 
784
<span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span> <span class="n">declarative_base</span>
 
785
<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="n">relationship</span>
 
786
 
 
787
<span class="n">Base</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">()</span>
 
788
 
 
789
<span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
 
790
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;user&#39;</span>
 
791
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
 
792
    <span class="n">name</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">)</span>
 
793
    <span class="n">addresses</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="s">&quot;Address&quot;</span><span class="p">,</span>
 
794
                    <span class="n">primaryjoin</span><span class="o">=</span><span class="s">&quot;and_(User.id==Address.user_id, &quot;</span>
 
795
                        <span class="s">&quot;Address.email.startswith(&#39;tony&#39;))&quot;</span><span class="p">,</span>
 
796
                    <span class="n">back_populates</span><span class="o">=</span><span class="s">&quot;user&quot;</span><span class="p">)</span>
 
797
 
 
798
<span class="k">class</span> <span class="nc">Address</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
 
799
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;address&#39;</span>
 
800
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
 
801
    <span class="n">email</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">)</span>
 
802
    <span class="n">user_id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s">&#39;user.id&#39;</span><span class="p">))</span>
 
803
    <span class="n">user</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="s">&quot;User&quot;</span><span class="p">)</span></pre></div>
 
804
</div>
 
805
<p>With the above scenario, appending an <tt class="docutils literal"><span class="pre">Address</span></tt> object to the <tt class="docutils literal"><span class="pre">.addresses</span></tt>
 
806
collection of a <tt class="docutils literal"><span class="pre">User</span></tt> will always establish the <tt class="docutils literal"><span class="pre">.user</span></tt> attribute on that
 
807
<tt class="docutils literal"><span class="pre">Address</span></tt>:</p>
 
808
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">u1</span> <span class="o">=</span> <span class="n">User</span><span class="p">()</span>
 
809
<span class="gp">&gt;&gt;&gt; </span><span class="n">a1</span> <span class="o">=</span> <span class="n">Address</span><span class="p">(</span><span class="n">email</span><span class="o">=</span><span class="s">&#39;tony&#39;</span><span class="p">)</span>
 
810
<span class="gp">&gt;&gt;&gt; </span><span class="n">u1</span><span class="o">.</span><span class="n">addresses</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">a1</span><span class="p">)</span>
 
811
<span class="gp">&gt;&gt;&gt; </span><span class="n">a1</span><span class="o">.</span><span class="n">user</span>
 
812
<span class="go">&lt;__main__.User object at 0x1411850&gt;</span></pre></div>
 
813
</div>
 
814
<p>However, applying a <tt class="docutils literal"><span class="pre">User</span></tt> to the <tt class="docutils literal"><span class="pre">.user</span></tt> attribute of an <tt class="docutils literal"><span class="pre">Address</span></tt>,
 
815
will not append the <tt class="docutils literal"><span class="pre">Address</span></tt> object to the collection:</p>
 
816
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">a2</span> <span class="o">=</span> <span class="n">Address</span><span class="p">(</span><span class="n">email</span><span class="o">=</span><span class="s">&#39;mary&#39;</span><span class="p">)</span>
 
817
<span class="gp">&gt;&gt;&gt; </span><span class="n">a2</span><span class="o">.</span><span class="n">user</span> <span class="o">=</span> <span class="n">u1</span>
 
818
<span class="gp">&gt;&gt;&gt; </span><span class="n">a2</span> <span class="ow">in</span> <span class="n">u1</span><span class="o">.</span><span class="n">addresses</span>
 
819
<span class="go">False</span></pre></div>
 
820
</div>
 
821
<p>Of course, we&#8217;ve disabled some of the usefulness of <tt class="docutils literal"><span class="pre">backref</span></tt> here, in that
 
822
when we do append an <tt class="docutils literal"><span class="pre">Address</span></tt> that corresponds to the criteria of <tt class="docutils literal"><span class="pre">email.startswith('tony')</span></tt>,
 
823
it won&#8217;t show up in the <tt class="docutils literal"><span class="pre">User.addresses</span></tt> collection until the session is flushed,
 
824
and the attributes reloaded after a commit or expire operation.   While we could
 
825
consider an attribute event that checks this criterion in Python, this starts
 
826
to cross the line of duplicating too much SQL behavior in Python.  The backref behavior
 
827
itself is only a slight transgression of this philosophy - SQLAlchemy tries to keep
 
828
these to a minimum overall.</p>
 
829
</div>
 
830
</div>
584
831
<div class="section" id="specifying-alternate-join-conditions-to-relationship">
585
 
<h2>Specifying Alternate Join Conditions to relationship()<a class="headerlink" href="#specifying-alternate-join-conditions-to-relationship" title="Permalink to this headline">¶</a></h2>
 
832
<span id="relationship-primaryjoin"></span><h2>Specifying Alternate Join Conditions to relationship()<a class="headerlink" href="#specifying-alternate-join-conditions-to-relationship" title="Permalink to this headline">¶</a></h2>
586
833
<p>The <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> function uses the foreign key
587
834
relationship between the parent and child tables to formulate the <strong>primary
588
835
join condition</strong> between parent and child; in the case of a many-to-many
603
850
                              secondaryjoin</pre>
604
851
</div>
605
852
<p>If you are working with a <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> which has no
606
 
<a class="reference internal" href="../core/schema.html#sqlalchemy.schema.ForeignKey" title="sqlalchemy.schema.ForeignKey"><tt class="xref py py-class docutils literal"><span class="pre">ForeignKey</span></tt></a> objects on it (which can be the case
 
853
<a class="reference internal" href="../core/schema.html#sqlalchemy.schema.ForeignKey" title="sqlalchemy.schema.ForeignKey"><tt class="xref py py-class docutils literal"><span class="pre">ForeignKey</span></tt></a> metadata established (which can be the case
607
854
when using reflected tables with MySQL), or if the join condition cannot be
608
 
expressed by a simple foreign key relationship, use the <tt class="docutils literal"><span class="pre">primaryjoin</span></tt> and
609
 
possibly <tt class="docutils literal"><span class="pre">secondaryjoin</span></tt> conditions to create the appropriate relationship.</p>
610
 
<p>In this example we create a relationship <tt class="docutils literal"><span class="pre">boston_addresses</span></tt> which will only
611
 
load the user addresses with a city of &#8220;Boston&#8221;:</p>
612
 
<div class="highlight-python+sql"><div class="highlight"><pre><span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
 
855
expressed by a simple foreign key relationship, use the <tt class="docutils literal"><span class="pre">primaryjoin</span></tt>, and
 
856
for many-to-many relationships <tt class="docutils literal"><span class="pre">secondaryjoin</span></tt>, directives
 
857
to create the appropriate relationship.</p>
 
858
<p>In this example, using the <tt class="docutils literal"><span class="pre">User</span></tt> class as well as an <tt class="docutils literal"><span class="pre">Address</span></tt> class
 
859
which stores a street address,  we create a relationship <tt class="docutils literal"><span class="pre">boston_addresses</span></tt> which will only
 
860
load those <tt class="docutils literal"><span class="pre">Address</span></tt> objects which specify a city of &#8220;Boston&#8221;:</p>
 
861
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">,</span> <span class="n">String</span><span class="p">,</span> <span class="n">Column</span>
 
862
<span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span> <span class="n">declarative_base</span>
 
863
<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="n">relationship</span>
 
864
 
 
865
<span class="n">Base</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">()</span>
 
866
 
 
867
<span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
 
868
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;user&#39;</span>
 
869
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
 
870
    <span class="n">name</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">)</span>
 
871
    <span class="n">addresses</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="s">&quot;Address&quot;</span><span class="p">,</span>
 
872
                    <span class="n">primaryjoin</span><span class="o">=</span><span class="s">&quot;and_(User.id==Address.user_id, &quot;</span>
 
873
                        <span class="s">&quot;Address.city==&#39;Boston&#39;)&quot;</span><span class="p">)</span>
 
874
 
 
875
<span class="k">class</span> <span class="nc">Address</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
 
876
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;address&#39;</span>
 
877
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
 
878
    <span class="n">user_id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s">&#39;user.id&#39;</span><span class="p">))</span>
 
879
 
 
880
    <span class="n">street</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">)</span>
 
881
    <span class="n">city</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">)</span>
 
882
    <span class="n">state</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">)</span>
 
883
    <span class="nb">zip</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">)</span></pre></div>
 
884
</div>
 
885
<p>Note above we specified the <tt class="docutils literal"><span class="pre">primaryjoin</span></tt> argument as a string - this feature
 
886
is available only when the mapping is constructed using the Declarative extension,
 
887
and allows us to specify a full SQL expression
 
888
between two entities before those entities have been fully constructed.   When
 
889
all mappings have been defined, an automatic &#8220;mapper configuration&#8221; step interprets
 
890
these string arguments when first needed.</p>
 
891
<p>Within this string SQL expression, we also made usage of the <a class="reference internal" href="../core/expression_api.html#sqlalchemy.sql.expression.and_" title="sqlalchemy.sql.expression.and_"><tt class="xref py py-func docutils literal"><span class="pre">and_()</span></tt></a> conjunction construct to establish
 
892
two distinct predicates for the join condition - joining both the <tt class="docutils literal"><span class="pre">User.id</span></tt> and
 
893
<tt class="docutils literal"><span class="pre">Address.user_id</span></tt> columns to each other, as well as limiting rows in <tt class="docutils literal"><span class="pre">Address</span></tt>
 
894
to just <tt class="docutils literal"><span class="pre">city='Boston'</span></tt>.   When using Declarative, rudimentary SQL functions like
 
895
<a class="reference internal" href="../core/expression_api.html#sqlalchemy.sql.expression.and_" title="sqlalchemy.sql.expression.and_"><tt class="xref py py-func docutils literal"><span class="pre">and_()</span></tt></a> are automatically available in the evaulated namespace of a string
 
896
<a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> argument.</p>
 
897
<p>When using classical mappings, we have the advantage of the <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> objects
 
898
already being present when the mapping is defined, so that the SQL expression
 
899
can be created immediately:</p>
 
900
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="n">relationship</span><span class="p">,</span> <span class="n">mapper</span>
 
901
 
 
902
<span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
613
903
    <span class="k">pass</span>
614
904
<span class="k">class</span> <span class="nc">Address</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
615
905
    <span class="k">pass</span>
617
907
<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>
618
908
<span class="n">mapper</span><span class="p">(</span><span class="n">User</span><span class="p">,</span> <span class="n">users_table</span><span class="p">,</span> <span class="n">properties</span><span class="o">=</span><span class="p">{</span>
619
909
    <span class="s">&#39;boston_addresses&#39;</span><span class="p">:</span> <span class="n">relationship</span><span class="p">(</span><span class="n">Address</span><span class="p">,</span> <span class="n">primaryjoin</span><span class="o">=</span>
620
 
                <span class="n">and_</span><span class="p">(</span><span class="n">users_table</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">user_id</span><span class="o">==</span><span class="n">addresses_table</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">user_id</span><span class="p">,</span>
 
910
                <span class="n">and_</span><span class="p">(</span><span class="n">users_table</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">id</span><span class="o">==</span><span class="n">addresses_table</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">user_id</span><span class="p">,</span>
621
911
                <span class="n">addresses_table</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">city</span><span class="o">==</span><span class="s">&#39;Boston&#39;</span><span class="p">))</span>
622
912
<span class="p">})</span></pre></div>
623
913
</div>
 
914
<p>Note that the custom criteria we use in a <tt class="docutils literal"><span class="pre">primaryjoin</span></tt> is generally only significant
 
915
when SQLAlchemy is rendering SQL in order to load or represent this relationship.
 
916
That is, it&#8217;s  used
 
917
in the SQL statement that&#8217;s emitted in order to perform a per-attribute lazy load, or when a join is
 
918
constructed at query time, such as via <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>, or via the eager &#8220;joined&#8221; or &#8220;subquery&#8221;
 
919
styles of loading.   When in-memory objects are being manipulated, we can place any <tt class="docutils literal"><span class="pre">Address</span></tt> object
 
920
we&#8217;d like into the <tt class="docutils literal"><span class="pre">boston_addresses</span></tt> collection, regardless of what the value of the <tt class="docutils literal"><span class="pre">.city</span></tt>
 
921
attribute is.   The objects will remain present in the collection until the attribute is expired
 
922
and re-loaded from the database where the criterion is applied.   When
 
923
a flush occurs, the objects inside of <tt class="docutils literal"><span class="pre">boston_addresses</span></tt> will be flushed unconditionally, assigning
 
924
value of the primary key <tt class="docutils literal"><span class="pre">user.id</span></tt> column onto the foreign-key-holding <tt class="docutils literal"><span class="pre">address.user_id</span></tt> column
 
925
for each row.  The <tt class="docutils literal"><span class="pre">city</span></tt> criteria has no effect here, as the flush process only cares about synchronizing primary
 
926
key values into referencing foreign key values.</p>
 
927
<div class="section" id="self-referential-many-to-many-relationship">
 
928
<span id="self-referential-many-to-many"></span><h3>Self-Referential Many-to-Many Relationship<a class="headerlink" href="#self-referential-many-to-many-relationship" title="Permalink to this headline">¶</a></h3>
624
929
<p>Many to many relationships can be customized by one or both of <tt class="docutils literal"><span class="pre">primaryjoin</span></tt>
625
 
and <tt class="docutils literal"><span class="pre">secondaryjoin</span></tt>, shown below with just the default many-to-many
626
 
relationship explicitly set:</p>
627
 
<div class="highlight-python+sql"><div class="highlight"><pre><span class="k">class</span> <span class="nc">User</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
628
 
    <span class="k">pass</span>
629
 
<span class="k">class</span> <span class="nc">Keyword</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
630
 
    <span class="k">pass</span>
631
 
<span class="n">mapper</span><span class="p">(</span><span class="n">Keyword</span><span class="p">,</span> <span class="n">keywords_table</span><span class="p">)</span>
632
 
<span class="n">mapper</span><span class="p">(</span><span class="n">User</span><span class="p">,</span> <span class="n">users_table</span><span class="p">,</span> <span class="n">properties</span><span class="o">=</span><span class="p">{</span>
633
 
    <span class="s">&#39;keywords&#39;</span><span class="p">:</span> <span class="n">relationship</span><span class="p">(</span><span class="n">Keyword</span><span class="p">,</span> <span class="n">secondary</span><span class="o">=</span><span class="n">userkeywords_table</span><span class="p">,</span>
634
 
        <span class="n">primaryjoin</span><span class="o">=</span><span class="n">users_table</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">user_id</span><span class="o">==</span><span class="n">userkeywords_table</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">user_id</span><span class="p">,</span>
635
 
        <span class="n">secondaryjoin</span><span class="o">=</span><span class="n">userkeywords_table</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">keyword_id</span><span class="o">==</span><span class="n">keywords_table</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">keyword_id</span>
636
 
        <span class="p">)</span>
637
 
<span class="p">})</span></pre></div>
 
930
and <tt class="docutils literal"><span class="pre">secondaryjoin</span></tt>.    A common situation for custom primary and secondary joins
 
931
is when establishing a many-to-many relationship from a class to itself, as shown below:</p>
 
932
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">,</span> <span class="n">String</span><span class="p">,</span> <span class="n">Column</span><span class="p">,</span> <span class="n">Table</span>
 
933
<span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span> <span class="n">declarative_base</span>
 
934
<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="n">relationship</span>
 
935
 
 
936
<span class="n">Base</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">()</span>
 
937
 
 
938
<span class="n">node_to_node</span> <span class="o">=</span> <span class="n">Table</span><span class="p">(</span><span class="s">&quot;node_to_node&quot;</span><span class="p">,</span> <span class="n">Base</span><span class="o">.</span><span class="n">metadata</span><span class="p">,</span>
 
939
    <span class="n">Column</span><span class="p">(</span><span class="s">&quot;left_node_id&quot;</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s">&quot;node.id&quot;</span><span class="p">),</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">),</span>
 
940
    <span class="n">Column</span><span class="p">(</span><span class="s">&quot;right_node_id&quot;</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s">&quot;node.id&quot;</span><span class="p">),</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
 
941
<span class="p">)</span>
 
942
 
 
943
<span class="k">class</span> <span class="nc">Node</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
 
944
    <span class="n">__tablename__</span> <span class="o">=</span> <span class="s">&#39;node&#39;</span>
 
945
    <span class="nb">id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
 
946
    <span class="n">label</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">)</span>
 
947
    <span class="n">right_nodes</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="s">&quot;Node&quot;</span><span class="p">,</span>
 
948
                        <span class="n">secondary</span><span class="o">=</span><span class="n">node_to_node</span><span class="p">,</span>
 
949
                        <span class="n">primaryjoin</span><span class="o">=</span><span class="nb">id</span><span class="o">==</span><span class="n">node_to_node</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">left_node_id</span><span class="p">,</span>
 
950
                        <span class="n">secondaryjoin</span><span class="o">=</span><span class="nb">id</span><span class="o">==</span><span class="n">node_to_node</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">right_node_id</span><span class="p">,</span>
 
951
                        <span class="n">backref</span><span class="o">=</span><span class="s">&quot;left_nodes&quot;</span>
 
952
    <span class="p">)</span></pre></div>
 
953
</div>
 
954
<p>Where above, SQLAlchemy can&#8217;t know automatically which columns should connect
 
955
to which for the <tt class="docutils literal"><span class="pre">right_nodes</span></tt> and <tt class="docutils literal"><span class="pre">left_nodes</span></tt> relationships.   The <tt class="docutils literal"><span class="pre">primaryjoin</span></tt>
 
956
and <tt class="docutils literal"><span class="pre">secondaryjoin</span></tt> arguments establish how we&#8217;d like to join to the association table.
 
957
In the Declarative form above, as we are declaring these conditions within the Python
 
958
block that corresponds to the <tt class="docutils literal"><span class="pre">Node</span></tt> class, the <tt class="docutils literal"><span class="pre">id</span></tt> variable is available directly
 
959
as the <tt class="docutils literal"><span class="pre">Column</span></tt> object we wish to join with.</p>
 
960
<p>A classical mapping situation here is similar, where <tt class="docutils literal"><span class="pre">node_to_node</span></tt> can be joined
 
961
to <tt class="docutils literal"><span class="pre">node.c.id</span></tt>:</p>
 
962
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">,</span> <span class="n">String</span><span class="p">,</span> <span class="n">Column</span><span class="p">,</span> <span class="n">Table</span><span class="p">,</span> <span class="n">MetaData</span>
 
963
<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="n">relationship</span><span class="p">,</span> <span class="n">mapper</span>
 
964
 
 
965
<span class="n">metadata</span> <span class="o">=</span> <span class="n">MetaData</span><span class="p">()</span>
 
966
 
 
967
<span class="n">node_to_node</span> <span class="o">=</span> <span class="n">Table</span><span class="p">(</span><span class="s">&quot;node_to_node&quot;</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span>
 
968
    <span class="n">Column</span><span class="p">(</span><span class="s">&quot;left_node_id&quot;</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s">&quot;node.id&quot;</span><span class="p">),</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">),</span>
 
969
    <span class="n">Column</span><span class="p">(</span><span class="s">&quot;right_node_id&quot;</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">ForeignKey</span><span class="p">(</span><span class="s">&quot;node.id&quot;</span><span class="p">),</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
 
970
<span class="p">)</span>
 
971
 
 
972
<span class="n">node</span> <span class="o">=</span> <span class="n">Table</span><span class="p">(</span><span class="s">&quot;node&quot;</span><span class="p">,</span> <span class="n">metadata</span><span class="p">,</span>
 
973
    <span class="n">Column</span><span class="p">(</span><span class="s">&#39;id&#39;</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">),</span>
 
974
    <span class="n">Column</span><span class="p">(</span><span class="s">&#39;label&#39;</span><span class="p">,</span> <span class="n">String</span><span class="p">)</span>
 
975
<span class="p">)</span>
 
976
<span class="k">class</span> <span class="nc">Node</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
 
977
    <span class="k">pass</span>
 
978
 
 
979
<span class="n">mapper</span><span class="p">(</span><span class="n">Node</span><span class="p">,</span> <span class="n">node</span><span class="p">,</span> <span class="n">properties</span><span class="o">=</span><span class="p">{</span>
 
980
    <span class="s">&#39;right_nodes&#39;</span><span class="p">:</span><span class="n">relationship</span><span class="p">(</span><span class="n">Node</span><span class="p">,</span>
 
981
                        <span class="n">secondary</span><span class="o">=</span><span class="n">node_to_node</span><span class="p">,</span>
 
982
                        <span class="n">primaryjoin</span><span class="o">=</span><span class="n">node</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">id</span><span class="o">==</span><span class="n">node_to_node</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">left_node_id</span><span class="p">,</span>
 
983
                        <span class="n">secondaryjoin</span><span class="o">=</span><span class="n">node</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">id</span><span class="o">==</span><span class="n">node_to_node</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">right_node_id</span><span class="p">,</span>
 
984
                        <span class="n">backref</span><span class="o">=</span><span class="s">&quot;left_nodes&quot;</span>
 
985
                    <span class="p">)})</span></pre></div>
 
986
</div>
 
987
<p>Note that in both examples, the <tt class="docutils literal"><span class="pre">backref</span></tt> keyword specifies a <tt class="docutils literal"><span class="pre">left_nodes</span></tt>
 
988
backref - when <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> creates the second relationship in the reverse
 
989
direction, it&#8217;s smart enough to reverse the <tt class="docutils literal"><span class="pre">primaryjoin</span></tt> and <tt class="docutils literal"><span class="pre">secondaryjoin</span></tt> arguments.</p>
638
990
</div>
639
991
<div class="section" id="specifying-foreign-keys">
640
992
<h3>Specifying Foreign Keys<a class="headerlink" href="#specifying-foreign-keys" title="Permalink to this headline">¶</a></h3>
798
1150
map for objects that may be referencing the one with a
799
1151
mutating primary key, not throughout the database.</p>
800
1152
</div>
801
 
<div class="section" id="the-relationship-api">
802
 
<h2>The <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> API<a class="headerlink" href="#the-relationship-api" title="Permalink to this headline">¶</a></h2>
 
1153
<div class="section" id="relationships-api">
 
1154
<h2>Relationships API<a class="headerlink" href="#relationships-api" title="Permalink to this headline">¶</a></h2>
803
1155
<dl class="function">
804
1156
<dt id="sqlalchemy.orm.relationship">
805
1157
<tt class="descclassname">sqlalchemy.orm.</tt><tt class="descname">relationship</tt><big>(</big><em>argument</em>, <em>secondary=None</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#sqlalchemy.orm.relationship" title="Permalink to this definition">¶</a></dt>
810
1162
<a class="reference internal" href="#sqlalchemy.orm.relation" title="sqlalchemy.orm.relation"><tt class="xref py py-func docutils literal"><span class="pre">relation()</span></tt></a> prior to version 0.6.</p>
811
1163
</div>
812
1164
<p>This corresponds to a parent-child or associative table relationship.  The
813
 
constructed class is an instance of <tt class="xref py py-class docutils literal"><span class="pre">RelationshipProperty</span></tt>.</p>
 
1165
constructed class is an instance of <a class="reference internal" href="internals.html#sqlalchemy.orm.properties.RelationshipProperty" title="sqlalchemy.orm.properties.RelationshipProperty"><tt class="xref py py-class docutils literal"><span class="pre">RelationshipProperty</span></tt></a>.</p>
814
1166
<p>A typical <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a>:</p>
815
1167
<div class="highlight-python"><div class="highlight"><pre><span class="n">mapper</span><span class="p">(</span><span class="n">Parent</span><span class="p">,</span> <span class="n">properties</span><span class="o">=</span><span class="p">{</span>
816
1168
  <span class="s">&#39;children&#39;</span><span class="p">:</span> <span class="n">relationship</span><span class="p">(</span><span class="n">Children</span><span class="p">)</span>
821
1173
<col class="field-body" />
822
1174
<tbody valign="top">
823
1175
<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
824
 
<li><strong>argument</strong> &#8211; a class or <tt class="xref py py-class docutils literal"><span class="pre">Mapper</span></tt> instance, representing the target of
 
1176
<li><strong>argument</strong> &#8211; a class or <a class="reference internal" href="mapper_config.html#sqlalchemy.orm.mapper.Mapper" title="sqlalchemy.orm.mapper.Mapper"><tt class="xref py py-class docutils literal"><span class="pre">Mapper</span></tt></a> instance, representing the target of
825
1177
the relationship.</li>
826
1178
<li><strong>secondary</strong> &#8211; for a many-to-many relationship, specifies the intermediary
827
1179
table. The <em>secondary</em> keyword argument should generally only
878
1230
</ul>
879
1231
</li>
880
1232
<li><strong>cascade_backrefs=True</strong> &#8211; <p>a boolean value indicating if the <tt class="docutils literal"><span class="pre">save-update</span></tt> cascade should
881
 
operate along a backref event.   When set to <tt class="xref docutils literal"><span class="pre">False</span></tt> on a
882
 
one-to-many relationship that has a many-to-one backref, assigning
883
 
a persistent object to the many-to-one attribute on a transient object
884
 
will not add the transient to the session.  Similarly, when
885
 
set to <tt class="xref docutils literal"><span class="pre">False</span></tt> on a many-to-one relationship that has a one-to-many
886
 
backref, appending a persistent object to the one-to-many collection
887
 
on a transient object will not add the transient to the session.</p>
 
1233
operate along an assignment event intercepted by a backref.   
 
1234
When set to <tt class="xref docutils literal"><span class="pre">False</span></tt>,
 
1235
the attribute managed by this relationship will not cascade
 
1236
an incoming transient object into the session of a
 
1237
persistent parent, if the event is received via backref.</p>
 
1238
<p>That is:</p>
 
1239
<div class="highlight-python"><div class="highlight"><pre><span class="n">mapper</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">a_table</span><span class="p">,</span> <span class="n">properties</span><span class="o">=</span><span class="p">{</span>
 
1240
    <span class="s">&#39;bs&#39;</span><span class="p">:</span><span class="n">relationship</span><span class="p">(</span><span class="n">B</span><span class="p">,</span> <span class="n">backref</span><span class="o">=</span><span class="s">&quot;a&quot;</span><span class="p">,</span> <span class="n">cascade_backrefs</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
 
1241
<span class="p">})</span></pre></div>
 
1242
</div>
 
1243
<p>If an <tt class="docutils literal"><span class="pre">A()</span></tt> is present in the session, assigning it to
 
1244
the &#8220;a&#8221; attribute on a transient <tt class="docutils literal"><span class="pre">B()</span></tt> will not place
 
1245
the <tt class="docutils literal"><span class="pre">B()</span></tt> into the session.   To set the flag in the other 
 
1246
direction, i.e. so that <tt class="docutils literal"><span class="pre">A().bs.append(B())</span></tt> won&#8217;t add 
 
1247
a transient <tt class="docutils literal"><span class="pre">A()</span></tt> into the session for a persistent <tt class="docutils literal"><span class="pre">B()</span></tt>:</p>
 
1248
<div class="highlight-python"><div class="highlight"><pre><span class="n">mapper</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">a_table</span><span class="p">,</span> <span class="n">properties</span><span class="o">=</span><span class="p">{</span>
 
1249
    <span class="s">&#39;bs&#39;</span><span class="p">:</span><span class="n">relationship</span><span class="p">(</span><span class="n">B</span><span class="p">,</span> 
 
1250
            <span class="n">backref</span><span class="o">=</span><span class="n">backref</span><span class="p">(</span><span class="s">&quot;a&quot;</span><span class="p">,</span> <span class="n">cascade_backrefs</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
 
1251
        <span class="p">)</span>
 
1252
<span class="p">})</span></pre></div>
 
1253
</div>
888
1254
<p><tt class="docutils literal"><span class="pre">cascade_backrefs</span></tt> is new in 0.6.5.</p>
889
1255
</li>
890
1256
<li><strong>collection_class</strong> &#8211; a class or callable that returns a new list-holding object. will
891
1257
be used in place of a plain list for storing elements.
892
1258
Behavior of this attribute is described in detail at
893
1259
<a class="reference internal" href="collections.html#custom-collections"><em>Customizing Collection Access</em></a>.</li>
894
 
<li><strong>comparator_factory</strong> &#8211; a class which extends <tt class="xref py py-class docutils literal"><span class="pre">RelationshipProperty.Comparator</span></tt> which
 
1260
<li><strong>comparator_factory</strong> &#8211; a class which extends <a class="reference internal" href="internals.html#sqlalchemy.orm.properties.RelationshipProperty.Comparator" title="sqlalchemy.orm.properties.RelationshipProperty.Comparator"><tt class="xref py py-class docutils literal"><span class="pre">RelationshipProperty.Comparator</span></tt></a> which
895
1261
provides custom SQL clause generation for comparison operations.</li>
896
1262
<li><strong>doc</strong> &#8211; docstring which will be applied to the resulting descriptor.</li>
897
 
<li><strong>extension</strong> &#8211; an <tt class="xref py py-class docutils literal"><span class="pre">AttributeExtension</span></tt> instance, or list of extensions,
 
1263
<li><strong>extension</strong> &#8211; an <a class="reference internal" href="interfaces.html#sqlalchemy.orm.interfaces.AttributeExtension" title="sqlalchemy.orm.interfaces.AttributeExtension"><tt class="xref py py-class docutils literal"><span class="pre">AttributeExtension</span></tt></a> instance, or list of extensions,
898
1264
which will be prepended to the list of attribute listeners for
899
 
the resulting descriptor placed on the class.  These listeners
900
 
will receive append and set events before the operation
901
 
proceeds, and may be used to halt (via exception throw) or
902
 
change the value used in the operation.</li>
 
1265
the resulting descriptor placed on the class.
 
1266
<strong>Deprecated.</strong>  Please see <a class="reference internal" href="events.html#sqlalchemy.orm.events.AttributeEvents" title="sqlalchemy.orm.events.AttributeEvents"><tt class="xref py py-class docutils literal"><span class="pre">AttributeEvents</span></tt></a>.</li>
903
1267
<li><strong>foreign_keys</strong> &#8211; <p>a list of columns which are to be used as &#8220;foreign key&#8221; columns.
904
1268
Normally, <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> uses the <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.ForeignKey" title="sqlalchemy.schema.ForeignKey"><tt class="xref py py-class docutils literal"><span class="pre">ForeignKey</span></tt></a>
905
1269
and <a class="reference internal" href="../core/schema.html#sqlalchemy.schema.ForeignKeyConstraint" title="sqlalchemy.schema.ForeignKeyConstraint"><tt class="xref py py-class docutils literal"><span class="pre">ForeignKeyConstraint</span></tt></a> objects present within the
1059
1423
table).</li>
1060
1424
<li><strong>remote_side</strong> &#8211; used for self-referential relationships, indicates the column or
1061
1425
list of columns that form the &#8220;remote side&#8221; of the relationship.</li>
 
1426
<li><strong>query_class</strong> &#8211; a <a class="reference internal" href="query.html#sqlalchemy.orm.query.Query" title="sqlalchemy.orm.query.Query"><tt class="xref py py-class docutils literal"><span class="pre">Query</span></tt></a> subclass that will be used as the base of the
 
1427
&#8220;appender query&#8221; returned by a &#8220;dynamic&#8221; relationship, that
 
1428
is, a relationship that specifies <tt class="docutils literal"><span class="pre">lazy=&quot;dynamic&quot;</span></tt> or was 
 
1429
otherwise constructed using the <a class="reference internal" href="#sqlalchemy.orm.dynamic_loader" title="sqlalchemy.orm.dynamic_loader"><tt class="xref py py-func docutils literal"><span class="pre">orm.dynamic_loader()</span></tt></a>
 
1430
function.</li>
1062
1431
<li><strong>secondaryjoin</strong> &#8211; a ColumnElement (i.e. WHERE criterion) that will be used as the join of
1063
1432
an association table to the child object. By default, this value is
1064
1433
computed based on the foreign key relationships of the association and
1094
1463
<dl class="function">
1095
1464
<dt id="sqlalchemy.orm.backref">
1096
1465
<tt class="descclassname">sqlalchemy.orm.</tt><tt class="descname">backref</tt><big>(</big><em>name</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#sqlalchemy.orm.backref" title="Permalink to this definition">¶</a></dt>
1097
 
<dd><p>Create a back reference with explicit arguments, which are the same
 
1466
<dd><p>Create a back reference with explicit keyword arguments, which are the same
1098
1467
arguments one can send to <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a>.</p>
1099
 
<p>Used with the <cite>backref</cite> keyword argument to <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> in
1100
 
place of a string argument.</p>
 
1468
<p>Used with the <tt class="docutils literal"><span class="pre">backref</span></tt> keyword argument to <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> in
 
1469
place of a string argument, e.g.:</p>
 
1470
<div class="highlight-python"><pre>'items':relationship(SomeItem, backref=backref('parent', lazy='subquery'))</pre>
 
1471
</div>
1101
1472
</dd></dl>
1102
1473
 
1103
1474
<dl class="function">
1106
1477
<dd><p>A synonym for <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a>.</p>
1107
1478
</dd></dl>
1108
1479
 
 
1480
<dl class="function">
 
1481
<dt id="sqlalchemy.orm.dynamic_loader">
 
1482
<tt class="descclassname">sqlalchemy.orm.</tt><tt class="descname">dynamic_loader</tt><big>(</big><em>argument</em>, <em>**kw</em><big>)</big><a class="headerlink" href="#sqlalchemy.orm.dynamic_loader" title="Permalink to this definition">¶</a></dt>
 
1483
<dd><p>Construct a dynamically-loading mapper property.</p>
 
1484
<p>This is essentially the same as 
 
1485
using the <tt class="docutils literal"><span class="pre">lazy='dynamic'</span></tt> argument with <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a>:</p>
 
1486
<div class="highlight-python"><div class="highlight"><pre><span class="n">dynamic_loader</span><span class="p">(</span><span class="n">SomeClass</span><span class="p">)</span>
 
1487
 
 
1488
<span class="c"># vs.</span>
 
1489
 
 
1490
<span class="n">relationship</span><span class="p">(</span><span class="n">SomeClass</span><span class="p">,</span> <span class="n">lazy</span><span class="o">=</span><span class="s">&quot;dynamic&quot;</span><span class="p">)</span></pre></div>
 
1491
</div>
 
1492
<p>A <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> that is &#8220;dynamic&#8221; features the behavior
 
1493
that read operations return an active <a class="reference internal" href="query.html#sqlalchemy.orm.query.Query" title="sqlalchemy.orm.query.Query"><tt class="xref py py-class docutils literal"><span class="pre">Query</span></tt></a> object which 
 
1494
reads from the database when accessed. Items may be appended to the
 
1495
attribute via <tt class="docutils literal"><span class="pre">append()</span></tt>, or removed via <tt class="docutils literal"><span class="pre">remove()</span></tt>; changes will be
 
1496
persisted to the database during a <tt class="xref py py-meth docutils literal"><span class="pre">Sesion.flush()</span></tt>. However, no other
 
1497
Python list or collection mutation operations are available.</p>
 
1498
<p>All arguments accepted by <a class="reference internal" href="#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> are
 
1499
accepted here, other than <tt class="docutils literal"><span class="pre">lazy</span></tt> which is fixed at <tt class="docutils literal"><span class="pre">dynamic</span></tt>.</p>
 
1500
</dd></dl>
 
1501
 
1109
1502
</div>
1110
1503
</div>
1111
1504