1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
<html xmlns="http://www.w3.org/1999/xhtml">
6
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
11
Frequently Asked Questions
13
SQLAlchemy 0.8 Documentation
17
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
18
<link rel="stylesheet" href="_static/docs.css" type="text/css" />
20
<script type="text/javascript">
21
var DOCUMENTATION_OPTIONS = {
24
COLLAPSE_MODINDEX: false,
28
<script type="text/javascript" src="_static/jquery.js"></script>
29
<script type="text/javascript" src="_static/underscore.js"></script>
30
<script type="text/javascript" src="_static/doctools.js"></script>
31
<script type="text/javascript" src="_static/init.js"></script>
32
<link rel="index" title="Index" href="genindex.html" />
33
<link rel="search" title="Search" href="search.html" />
34
<link rel="copyright" title="Copyright" href="copyright.html" />
35
<link rel="top" title="SQLAlchemy 0.8 Documentation" href="index.html" />
50
<div id="docs-container">
54
<div id="docs-header">
55
<h1>SQLAlchemy 0.8 Documentation</h1>
57
<div id="docs-search">
59
<form class="search" action="search.html" method="get">
60
<input type="text" name="q" size="18" /> <input type="submit" value="Search" />
61
<input type="hidden" name="check_keywords" value="yes" />
62
<input type="hidden" name="area" value="default" />
66
<div id="docs-version-header">
67
Release: <span class="version-num">0.8.3</span> | Release Date: October 26, 2013
74
<div id="docs-top-navigation">
75
<div id="docs-top-page-control" class="docs-navigation-links">
79
<a href="contents.html">Table of Contents</a> |
80
<a href="genindex.html">Index</a>
81
| <a href="_sources/faq.txt">view source
86
<div id="docs-navigation-banner">
87
<a href="index.html">SQLAlchemy 0.8 Documentation</a>
89
Frequently Asked Questions
94
Frequently Asked Questions
101
<div id="docs-body-container">
103
<div id="docs-sidebar">
104
<h3><a href="index.html">Table of Contents</a></h3>
106
<li><a class="reference internal" href="#">Frequently Asked Questions</a><ul>
107
<li><a class="reference internal" href="#connections-engines">Connections / Engines</a><ul>
108
<li><a class="reference internal" href="#how-do-i-configure-logging">How do I configure logging?</a></li>
109
<li><a class="reference internal" href="#how-do-i-pool-database-connections-are-my-connections-pooled">How do I pool database connections? Are my connections pooled?</a></li>
110
<li><a class="reference internal" href="#how-do-i-pass-custom-connect-arguments-to-my-database-api">How do I pass custom connect arguments to my database API?</a></li>
111
<li><a class="reference internal" href="#mysql-server-has-gone-away">“MySQL Server has gone away”</a></li>
112
<li><a class="reference internal" href="#why-does-sqlalchemy-issue-so-many-rollbacks">Why does SQLAlchemy issue so many ROLLBACKs?</a><ul>
113
<li><a class="reference internal" href="#i-m-on-myisam-how-do-i-turn-it-off">I’m on MyISAM - how do I turn it off?</a></li>
114
<li><a class="reference internal" href="#i-m-on-sql-server-how-do-i-turn-those-rollbacks-into-commits">I’m on SQL Server - how do I turn those ROLLBACKs into COMMITs?</a></li>
117
<li><a class="reference internal" href="#i-am-using-multiple-connections-with-a-sqlite-database-typically-to-test-transaction-operation-and-my-test-program-is-not-working">I am using multiple connections with a SQLite database (typically to test transaction operation), and my test program is not working!</a></li>
118
<li><a class="reference internal" href="#how-do-i-get-at-the-raw-dbapi-connection-when-using-an-engine">How do I get at the raw DBAPI connection when using an Engine?</a></li>
121
<li><a class="reference internal" href="#metadata-schema">MetaData / Schema</a><ul>
122
<li><a class="reference internal" href="#my-program-is-hanging-when-i-say-table-drop-metadata-drop-all">My program is hanging when I say <tt class="docutils literal"><span class="pre">table.drop()</span></tt> / <tt class="docutils literal"><span class="pre">metadata.drop_all()</span></tt></a></li>
123
<li><a class="reference internal" href="#does-sqlalchemy-support-alter-table-create-view-create-trigger-schema-upgrade-functionality">Does SQLAlchemy support ALTER TABLE, CREATE VIEW, CREATE TRIGGER, Schema Upgrade Functionality?</a></li>
124
<li><a class="reference internal" href="#how-can-i-sort-table-objects-in-order-of-their-dependency">How can I sort Table objects in order of their dependency?</a></li>
125
<li><a class="reference internal" href="#how-can-i-get-the-create-table-drop-table-output-as-a-string">How can I get the CREATE TABLE/ DROP TABLE output as a string?</a></li>
126
<li><a class="reference internal" href="#how-can-i-subclass-table-column-to-provide-certain-behaviors-configurations">How can I subclass Table/Column to provide certain behaviors/configurations?</a></li>
129
<li><a class="reference internal" href="#sql-expressions">SQL Expressions</a><ul>
130
<li><a class="reference internal" href="#why-does-col-in-produce-col-col-why-not-1-0">Why does <tt class="docutils literal"><span class="pre">.col.in_([])</span></tt> Produce <tt class="docutils literal"><span class="pre">col</span> <span class="pre">!=</span> <span class="pre">col</span></tt>? Why not <tt class="docutils literal"><span class="pre">1=0</span></tt>?</a></li>
133
<li><a class="reference internal" href="#orm-configuration">ORM Configuration</a><ul>
134
<li><a class="reference internal" href="#how-do-i-map-a-table-that-has-no-primary-key">How do I map a table that has no primary key?</a></li>
135
<li><a class="reference internal" href="#how-do-i-configure-a-column-that-is-a-python-reserved-word-or-similar">How do I configure a Column that is a Python reserved word or similar?</a></li>
136
<li><a class="reference internal" href="#how-do-i-get-a-list-of-all-columns-relationships-mapped-attributes-etc-given-a-mapped-class">How do I get a list of all columns, relationships, mapped attributes, etc. given a mapped class?</a></li>
137
<li><a class="reference internal" href="#i-m-using-declarative-and-setting-primaryjoin-secondaryjoin-using-an-and-or-or-and-i-am-getting-an-error-message-about-foreign-keys">I’m using Declarative and setting primaryjoin/secondaryjoin using an <tt class="docutils literal"><span class="pre">and_()</span></tt> or <tt class="docutils literal"><span class="pre">or_()</span></tt>, and I am getting an error message about foreign keys.</a></li>
140
<li><a class="reference internal" href="#sessions-queries">Sessions / Queries</a><ul>
141
<li><a class="reference internal" href="#this-session-s-transaction-has-been-rolled-back-due-to-a-previous-exception-during-flush-or-similar">“This Session’s transaction has been rolled back due to a previous exception during flush.” (or similar)</a><ul>
142
<li><a class="reference internal" href="#but-why-does-flush-insist-on-issuing-a-rollback">But why does flush() insist on issuing a ROLLBACK?</a></li>
143
<li><a class="reference internal" href="#but-why-isn-t-the-one-automatic-call-to-rollback-enough-why-must-i-rollback-again">But why isn’t the one automatic call to ROLLBACK enough? Why must I ROLLBACK again?</a></li>
146
<li><a class="reference internal" href="#i-m-inserting-400-000-rows-with-the-orm-and-it-s-really-slow">I’m inserting 400,000 rows with the ORM and it’s really slow!</a></li>
147
<li><a class="reference internal" href="#how-do-i-make-a-query-that-always-adds-a-certain-filter-to-every-query">How do I make a Query that always adds a certain filter to every query?</a></li>
148
<li><a class="reference internal" href="#i-ve-created-a-mapping-against-an-outer-join-and-while-the-query-returns-rows-no-objects-are-returned-why-not">I’ve created a mapping against an Outer Join, and while the query returns rows, no objects are returned. Why not?</a></li>
149
<li><a class="reference internal" href="#i-m-using-joinedload-or-lazy-false-to-create-a-join-outer-join-and-sqlalchemy-is-not-constructing-the-correct-query-when-i-try-to-add-a-where-order-by-limit-etc-which-relies-upon-the-outer-join">I’m using <tt class="docutils literal"><span class="pre">joinedload()</span></tt> or <tt class="docutils literal"><span class="pre">lazy=False</span></tt> to create a JOIN/OUTER JOIN and SQLAlchemy is not constructing the correct query when I try to add a WHERE, ORDER BY, LIMIT, etc. (which relies upon the (OUTER) JOIN)</a></li>
150
<li><a class="reference internal" href="#query-has-no-len-why-not">Query has no <tt class="docutils literal"><span class="pre">__len__()</span></tt>, why not?</a></li>
151
<li><a class="reference internal" href="#how-do-i-use-textual-sql-with-orm-queries">How Do I use Textual SQL with ORM Queries?</a></li>
152
<li><a class="reference internal" href="#i-m-calling-session-delete-myobject-and-it-isn-t-removed-from-the-parent-collection">I’m calling <tt class="docutils literal"><span class="pre">Session.delete(myobject)</span></tt> and it isn’t removed from the parent collection!</a></li>
153
<li><a class="reference internal" href="#why-isnt-my-init-called-when-i-load-objects">why isnt my <tt class="docutils literal"><span class="pre">__init__()</span></tt> called when I load objects?</a></li>
154
<li><a class="reference internal" href="#how-do-i-use-on-delete-cascade-with-sa-s-orm">how do I use ON DELETE CASCADE with SA’s ORM?</a></li>
155
<li><a class="reference internal" href="#i-set-the-foo-id-attribute-on-my-instance-to-7-but-the-foo-attribute-is-still-none-shouldn-t-it-have-loaded-foo-with-id-7">I set the “foo_id” attribute on my instance to “7”, but the “foo” attribute is still <tt class="docutils literal"><span class="pre">None</span></tt> - shouldn’t it have loaded Foo with id #7?</a></li>
156
<li><a class="reference internal" href="#is-there-a-way-to-automagically-have-only-unique-keywords-or-other-kinds-of-objects-without-doing-a-query-for-the-keyword-and-getting-a-reference-to-the-row-containing-that-keyword">Is there a way to automagically have only unique keywords (or other kinds of objects) without doing a query for the keyword and getting a reference to the row containing that keyword?</a></li>
166
<h4>Quick Search</h4>
168
<form class="search" action="search.html" method="get">
169
<input type="text" name="q" size="18" /> <input type="submit" value="Search" />
170
<input type="hidden" name="check_keywords" value="yes" />
171
<input type="hidden" name="area" value="default" />
177
<div id="docs-body" class="withsidebar" >
179
<div class="section" id="frequently-asked-questions">
180
<span id="faq-toplevel"></span><h1>Frequently Asked Questions<a class="headerlink" href="#frequently-asked-questions" title="Permalink to this headline">¶</a></h1>
181
<div class="contents faq local topic" id="contents">
183
<li><a class="reference internal" href="#connections-engines" id="id1">Connections / Engines</a><ul>
184
<li><a class="reference internal" href="#how-do-i-configure-logging" id="id2">How do I configure logging?</a></li>
185
<li><a class="reference internal" href="#how-do-i-pool-database-connections-are-my-connections-pooled" id="id3">How do I pool database connections? Are my connections pooled?</a></li>
186
<li><a class="reference internal" href="#how-do-i-pass-custom-connect-arguments-to-my-database-api" id="id4">How do I pass custom connect arguments to my database API?</a></li>
187
<li><a class="reference internal" href="#mysql-server-has-gone-away" id="id5">“MySQL Server has gone away”</a></li>
188
<li><a class="reference internal" href="#why-does-sqlalchemy-issue-so-many-rollbacks" id="id6">Why does SQLAlchemy issue so many ROLLBACKs?</a><ul>
189
<li><a class="reference internal" href="#i-m-on-myisam-how-do-i-turn-it-off" id="id7">I’m on MyISAM - how do I turn it off?</a></li>
190
<li><a class="reference internal" href="#i-m-on-sql-server-how-do-i-turn-those-rollbacks-into-commits" id="id8">I’m on SQL Server - how do I turn those ROLLBACKs into COMMITs?</a></li>
193
<li><a class="reference internal" href="#i-am-using-multiple-connections-with-a-sqlite-database-typically-to-test-transaction-operation-and-my-test-program-is-not-working" id="id9">I am using multiple connections with a SQLite database (typically to test transaction operation), and my test program is not working!</a></li>
194
<li><a class="reference internal" href="#how-do-i-get-at-the-raw-dbapi-connection-when-using-an-engine" id="id10">How do I get at the raw DBAPI connection when using an Engine?</a></li>
197
<li><a class="reference internal" href="#metadata-schema" id="id11">MetaData / Schema</a><ul>
198
<li><a class="reference internal" href="#my-program-is-hanging-when-i-say-table-drop-metadata-drop-all" id="id12">My program is hanging when I say <tt class="docutils literal"><span class="pre">table.drop()</span></tt> / <tt class="docutils literal"><span class="pre">metadata.drop_all()</span></tt></a></li>
199
<li><a class="reference internal" href="#does-sqlalchemy-support-alter-table-create-view-create-trigger-schema-upgrade-functionality" id="id13">Does SQLAlchemy support ALTER TABLE, CREATE VIEW, CREATE TRIGGER, Schema Upgrade Functionality?</a></li>
200
<li><a class="reference internal" href="#how-can-i-sort-table-objects-in-order-of-their-dependency" id="id14">How can I sort Table objects in order of their dependency?</a></li>
201
<li><a class="reference internal" href="#how-can-i-get-the-create-table-drop-table-output-as-a-string" id="id15">How can I get the CREATE TABLE/ DROP TABLE output as a string?</a></li>
202
<li><a class="reference internal" href="#how-can-i-subclass-table-column-to-provide-certain-behaviors-configurations" id="id16">How can I subclass Table/Column to provide certain behaviors/configurations?</a></li>
205
<li><a class="reference internal" href="#sql-expressions" id="id17">SQL Expressions</a><ul>
206
<li><a class="reference internal" href="#why-does-col-in-produce-col-col-why-not-1-0" id="id18">Why does <tt class="docutils literal"><span class="pre">.col.in_([])</span></tt> Produce <tt class="docutils literal"><span class="pre">col</span> <span class="pre">!=</span> <span class="pre">col</span></tt>? Why not <tt class="docutils literal"><span class="pre">1=0</span></tt>?</a></li>
209
<li><a class="reference internal" href="#orm-configuration" id="id19">ORM Configuration</a><ul>
210
<li><a class="reference internal" href="#how-do-i-map-a-table-that-has-no-primary-key" id="id20">How do I map a table that has no primary key?</a></li>
211
<li><a class="reference internal" href="#how-do-i-configure-a-column-that-is-a-python-reserved-word-or-similar" id="id21">How do I configure a Column that is a Python reserved word or similar?</a></li>
212
<li><a class="reference internal" href="#how-do-i-get-a-list-of-all-columns-relationships-mapped-attributes-etc-given-a-mapped-class" id="id22">How do I get a list of all columns, relationships, mapped attributes, etc. given a mapped class?</a></li>
213
<li><a class="reference internal" href="#i-m-using-declarative-and-setting-primaryjoin-secondaryjoin-using-an-and-or-or-and-i-am-getting-an-error-message-about-foreign-keys" id="id23">I’m using Declarative and setting primaryjoin/secondaryjoin using an <tt class="docutils literal"><span class="pre">and_()</span></tt> or <tt class="docutils literal"><span class="pre">or_()</span></tt>, and I am getting an error message about foreign keys.</a></li>
216
<li><a class="reference internal" href="#sessions-queries" id="id24">Sessions / Queries</a><ul>
217
<li><a class="reference internal" href="#this-session-s-transaction-has-been-rolled-back-due-to-a-previous-exception-during-flush-or-similar" id="id25">“This Session’s transaction has been rolled back due to a previous exception during flush.” (or similar)</a><ul>
218
<li><a class="reference internal" href="#but-why-does-flush-insist-on-issuing-a-rollback" id="id26">But why does flush() insist on issuing a ROLLBACK?</a></li>
219
<li><a class="reference internal" href="#but-why-isn-t-the-one-automatic-call-to-rollback-enough-why-must-i-rollback-again" id="id27">But why isn’t the one automatic call to ROLLBACK enough? Why must I ROLLBACK again?</a></li>
222
<li><a class="reference internal" href="#i-m-inserting-400-000-rows-with-the-orm-and-it-s-really-slow" id="id28">I’m inserting 400,000 rows with the ORM and it’s really slow!</a></li>
223
<li><a class="reference internal" href="#how-do-i-make-a-query-that-always-adds-a-certain-filter-to-every-query" id="id29">How do I make a Query that always adds a certain filter to every query?</a></li>
224
<li><a class="reference internal" href="#i-ve-created-a-mapping-against-an-outer-join-and-while-the-query-returns-rows-no-objects-are-returned-why-not" id="id30">I’ve created a mapping against an Outer Join, and while the query returns rows, no objects are returned. Why not?</a></li>
225
<li><a class="reference internal" href="#i-m-using-joinedload-or-lazy-false-to-create-a-join-outer-join-and-sqlalchemy-is-not-constructing-the-correct-query-when-i-try-to-add-a-where-order-by-limit-etc-which-relies-upon-the-outer-join" id="id31">I’m using <tt class="docutils literal"><span class="pre">joinedload()</span></tt> or <tt class="docutils literal"><span class="pre">lazy=False</span></tt> to create a JOIN/OUTER JOIN and SQLAlchemy is not constructing the correct query when I try to add a WHERE, ORDER BY, LIMIT, etc. (which relies upon the (OUTER) JOIN)</a></li>
226
<li><a class="reference internal" href="#query-has-no-len-why-not" id="id32">Query has no <tt class="docutils literal"><span class="pre">__len__()</span></tt>, why not?</a></li>
227
<li><a class="reference internal" href="#how-do-i-use-textual-sql-with-orm-queries" id="id33">How Do I use Textual SQL with ORM Queries?</a></li>
228
<li><a class="reference internal" href="#i-m-calling-session-delete-myobject-and-it-isn-t-removed-from-the-parent-collection" id="id34">I’m calling <tt class="docutils literal"><span class="pre">Session.delete(myobject)</span></tt> and it isn’t removed from the parent collection!</a></li>
229
<li><a class="reference internal" href="#why-isnt-my-init-called-when-i-load-objects" id="id35">why isnt my <tt class="docutils literal"><span class="pre">__init__()</span></tt> called when I load objects?</a></li>
230
<li><a class="reference internal" href="#how-do-i-use-on-delete-cascade-with-sa-s-orm" id="id36">how do I use ON DELETE CASCADE with SA’s ORM?</a></li>
231
<li><a class="reference internal" href="#i-set-the-foo-id-attribute-on-my-instance-to-7-but-the-foo-attribute-is-still-none-shouldn-t-it-have-loaded-foo-with-id-7" id="id37">I set the “foo_id” attribute on my instance to “7”, but the “foo” attribute is still <tt class="docutils literal"><span class="pre">None</span></tt> - shouldn’t it have loaded Foo with id #7?</a></li>
232
<li><a class="reference internal" href="#is-there-a-way-to-automagically-have-only-unique-keywords-or-other-kinds-of-objects-without-doing-a-query-for-the-keyword-and-getting-a-reference-to-the-row-containing-that-keyword" id="id38">Is there a way to automagically have only unique keywords (or other kinds of objects) without doing a query for the keyword and getting a reference to the row containing that keyword?</a></li>
237
<div class="section" id="connections-engines">
238
<h2>Connections / Engines<a class="headerlink" href="#connections-engines" title="Permalink to this headline">¶</a></h2>
239
<div class="section" id="how-do-i-configure-logging">
240
<h3>How do I configure logging?<a class="headerlink" href="#how-do-i-configure-logging" title="Permalink to this headline">¶</a></h3>
241
<p>See <a class="reference internal" href="core/engines.html#dbengine-logging"><em>Configuring Logging</em></a>.</p>
243
<div class="section" id="how-do-i-pool-database-connections-are-my-connections-pooled">
244
<h3>How do I pool database connections? Are my connections pooled?<a class="headerlink" href="#how-do-i-pool-database-connections-are-my-connections-pooled" title="Permalink to this headline">¶</a></h3>
245
<p>SQLAlchemy performs application-level connection pooling automatically
246
in most cases. With the exception of SQLite, a <a class="reference internal" href="core/connections.html#sqlalchemy.engine.Engine" title="sqlalchemy.engine.Engine"><tt class="xref py py-class docutils literal"><span class="pre">Engine</span></tt></a> object
247
refers to a <a class="reference internal" href="core/pooling.html#sqlalchemy.pool.QueuePool" title="sqlalchemy.pool.QueuePool"><tt class="xref py py-class docutils literal"><span class="pre">QueuePool</span></tt></a> as a source of connectivity.</p>
248
<p>For more detail, see <a class="reference internal" href="core/engines.html"><em>Engine Configuration</em></a> and <a class="reference internal" href="core/pooling.html"><em>Connection Pooling</em></a>.</p>
250
<div class="section" id="how-do-i-pass-custom-connect-arguments-to-my-database-api">
251
<h3>How do I pass custom connect arguments to my database API?<a class="headerlink" href="#how-do-i-pass-custom-connect-arguments-to-my-database-api" title="Permalink to this headline">¶</a></h3>
252
<p>The <a class="reference internal" href="core/engines.html#sqlalchemy.create_engine" title="sqlalchemy.create_engine"><tt class="xref py py-func docutils literal"><span class="pre">create_engine()</span></tt></a> call accepts additional arguments either
253
directly via the <tt class="docutils literal"><span class="pre">connect_args</span></tt> keyword argument:</p>
254
<div class="highlight-python"><div class="highlight"><pre><span class="n">e</span> <span class="o">=</span> <span class="n">create_engine</span><span class="p">(</span><span class="s">"mysql://scott:tiger@localhost/test"</span><span class="p">,</span>
255
<span class="n">connect_args</span><span class="o">=</span><span class="p">{</span><span class="s">"encoding"</span><span class="p">:</span> <span class="s">"utf8"</span><span class="p">})</span></pre></div>
257
<p>Or for basic string and integer arguments, they can usually be specified
258
in the query string of the URL:</p>
259
<div class="highlight-python"><div class="highlight"><pre><span class="n">e</span> <span class="o">=</span> <span class="n">create_engine</span><span class="p">(</span><span class="s">"mysql://scott:tiger@localhost/test?encoding=utf8"</span><span class="p">)</span></pre></div>
261
<div class="admonition seealso">
262
<p class="first admonition-title">See also</p>
263
<p class="last"><a class="reference internal" href="core/engines.html#custom-dbapi-args"><em>Custom DBAPI connect() arguments</em></a></p>
266
<div class="section" id="mysql-server-has-gone-away">
267
<h3>“MySQL Server has gone away”<a class="headerlink" href="#mysql-server-has-gone-away" title="Permalink to this headline">¶</a></h3>
268
<p>There are two major causes for this error:</p>
269
<p>1. The MySQL client closes connections which have been idle for a set period
270
of time, defaulting to eight hours. This can be avoided by using the <tt class="docutils literal"><span class="pre">pool_recycle</span></tt>
271
setting with <a class="reference internal" href="core/engines.html#sqlalchemy.create_engine" title="sqlalchemy.create_engine"><tt class="xref py py-func docutils literal"><span class="pre">create_engine()</span></tt></a>, described at <a class="reference internal" href="dialects/mysql.html#mysql-connection-timeouts"><em>Connection Timeouts</em></a>.</p>
272
<p>2. Usage of the MySQLdb <a class="reference internal" href="glossary.html#term-dbapi"><em class="xref std std-term">DBAPI</em></a>, or a similar DBAPI, in a non-threadsafe manner, or in an otherwise
273
inappropriate way. The MySQLdb connection object is not threadsafe - this expands
274
out to any SQLAlchemy system that links to a single connection, which includes the ORM
275
<a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session" title="sqlalchemy.orm.session.Session"><tt class="xref py py-class docutils literal"><span class="pre">Session</span></tt></a>. For background
276
on how <a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session" title="sqlalchemy.orm.session.Session"><tt class="xref py py-class docutils literal"><span class="pre">Session</span></tt></a> should be used in a multithreaded environment,
277
see <a class="reference internal" href="orm/session.html#session-faq-threadsafe"><em>Is the session thread-safe?</em></a>.</p>
279
<div class="section" id="why-does-sqlalchemy-issue-so-many-rollbacks">
280
<h3>Why does SQLAlchemy issue so many ROLLBACKs?<a class="headerlink" href="#why-does-sqlalchemy-issue-so-many-rollbacks" title="Permalink to this headline">¶</a></h3>
281
<p>SQLAlchemy currently assumes DBAPI connections are in “non-autocommit” mode -
282
this is the default behavior of the Python database API, meaning it
283
must be assumed that a transaction is always in progress. The
284
connection pool issues <tt class="docutils literal"><span class="pre">connection.rollback()</span></tt> when a connection is returned.
285
This is so that any transactional resources remaining on the connection are
286
released. On a database like Postgresql or MSSQL where table resources are
287
aggressively locked, this is critical so that rows and tables don’t remain
288
locked within connections that are no longer in use. An application can
289
otherwise hang. It’s not just for locks, however, and is equally critical on
290
any database that has any kind of transaction isolation, including MySQL with
291
InnoDB. Any connection that is still inside an old transaction will return
292
stale data, if that data was already queried on that connection within
293
isolation. For background on why you might see stale data even on MySQL, see
294
<a class="reference external" href="http://dev.mysql.com/doc/refman/5.1/en/innodb-transaction-model.html">http://dev.mysql.com/doc/refman/5.1/en/innodb-transaction-model.html</a></p>
295
<div class="section" id="i-m-on-myisam-how-do-i-turn-it-off">
296
<h4>I’m on MyISAM - how do I turn it off?<a class="headerlink" href="#i-m-on-myisam-how-do-i-turn-it-off" title="Permalink to this headline">¶</a></h4>
297
<p>The behavior of the connection pool’s connection return behavior can be
298
configured using <tt class="docutils literal"><span class="pre">reset_on_return</span></tt>:</p>
299
<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">create_engine</span>
300
<span class="kn">from</span> <span class="nn">sqlalchemy.pool</span> <span class="kn">import</span> <span class="n">QueuePool</span>
302
<span class="n">engine</span> <span class="o">=</span> <span class="n">create_engine</span><span class="p">(</span><span class="s">'mysql://scott:tiger@localhost/myisam_database'</span><span class="p">,</span> <span class="n">pool</span><span class="o">=</span><span class="n">QueuePool</span><span class="p">(</span><span class="n">reset_on_return</span><span class="o">=</span><span class="bp">False</span><span class="p">))</span></pre></div>
305
<div class="section" id="i-m-on-sql-server-how-do-i-turn-those-rollbacks-into-commits">
306
<h4>I’m on SQL Server - how do I turn those ROLLBACKs into COMMITs?<a class="headerlink" href="#i-m-on-sql-server-how-do-i-turn-those-rollbacks-into-commits" title="Permalink to this headline">¶</a></h4>
307
<p><tt class="docutils literal"><span class="pre">reset_on_return</span></tt> accepts the values <tt class="docutils literal"><span class="pre">commit</span></tt>, <tt class="docutils literal"><span class="pre">rollback</span></tt> in addition
308
to <tt class="docutils literal"><span class="pre">True</span></tt>, <tt class="docutils literal"><span class="pre">False</span></tt>, and <tt class="docutils literal"><span class="pre">None</span></tt>. Setting to <tt class="docutils literal"><span class="pre">commit</span></tt> will cause
309
a COMMIT as any connection is returned to the pool:</p>
310
<div class="highlight-python"><div class="highlight"><pre><span class="n">engine</span> <span class="o">=</span> <span class="n">create_engine</span><span class="p">(</span><span class="s">'mssql://scott:tiger@mydsn'</span><span class="p">,</span> <span class="n">pool</span><span class="o">=</span><span class="n">QueuePool</span><span class="p">(</span><span class="n">reset_on_return</span><span class="o">=</span><span class="s">'commit'</span><span class="p">))</span></pre></div>
314
<div class="section" id="i-am-using-multiple-connections-with-a-sqlite-database-typically-to-test-transaction-operation-and-my-test-program-is-not-working">
315
<h3>I am using multiple connections with a SQLite database (typically to test transaction operation), and my test program is not working!<a class="headerlink" href="#i-am-using-multiple-connections-with-a-sqlite-database-typically-to-test-transaction-operation-and-my-test-program-is-not-working" title="Permalink to this headline">¶</a></h3>
316
<p>If using a SQLite <tt class="docutils literal"><span class="pre">:memory:</span></tt> database, or a version of SQLAlchemy prior
317
to version 0.7, the default connection pool is the <a class="reference internal" href="core/pooling.html#sqlalchemy.pool.SingletonThreadPool" title="sqlalchemy.pool.SingletonThreadPool"><tt class="xref py py-class docutils literal"><span class="pre">SingletonThreadPool</span></tt></a>,
318
which maintains exactly one SQLite connection per thread. So two
319
connections in use in the same thread will actually be the same SQLite
320
connection. Make sure you’re not using a :memory: database and
321
use <a class="reference internal" href="core/pooling.html#sqlalchemy.pool.NullPool" title="sqlalchemy.pool.NullPool"><tt class="xref py py-class docutils literal"><span class="pre">NullPool</span></tt></a>, which is the default for non-memory databases in
322
current SQLAlchemy versions.</p>
323
<div class="admonition seealso">
324
<p class="first admonition-title">See also</p>
325
<p class="last"><a class="reference internal" href="dialects/sqlite.html#pysqlite-threading-pooling"><em>Threading/Pooling Behavior</em></a> - info on PySQLite’s behavior.</p>
328
<div class="section" id="how-do-i-get-at-the-raw-dbapi-connection-when-using-an-engine">
329
<h3>How do I get at the raw DBAPI connection when using an Engine?<a class="headerlink" href="#how-do-i-get-at-the-raw-dbapi-connection-when-using-an-engine" title="Permalink to this headline">¶</a></h3>
330
<p>With a regular SA engine-level Connection, you can get at a pool-proxied
331
version of the DBAPI connection via the <a class="reference internal" href="core/connections.html#sqlalchemy.engine.Connection.connection" title="sqlalchemy.engine.Connection.connection"><tt class="xref py py-attr docutils literal"><span class="pre">Connection.connection</span></tt></a> attribute on
332
<a class="reference internal" href="core/connections.html#sqlalchemy.engine.Connection" title="sqlalchemy.engine.Connection"><tt class="xref py py-class docutils literal"><span class="pre">Connection</span></tt></a>, and for the really-real DBAPI connection you can call the
333
<tt class="xref py py-attr docutils literal"><span class="pre">ConnectionFairy.connection</span></tt> attribute on that - but there should never be any need to access
334
the non-pool-proxied DBAPI connection, as all methods are proxied through:</p>
335
<div class="highlight-python"><pre>engine = create_engine(...)
336
conn = engine.connect()
337
conn.connection.<do DBAPI things>
338
cursor = conn.connection.cursor(<DBAPI specific arguments..>)</pre>
340
<p>You must ensure that you revert any isolation level settings or other
341
operation-specific settings on the connection back to normal before returning
343
<p>As an alternative to reverting settings, you can call the <a class="reference internal" href="core/connections.html#sqlalchemy.engine.Connection.detach" title="sqlalchemy.engine.Connection.detach"><tt class="xref py py-meth docutils literal"><span class="pre">Connection.detach()</span></tt></a> method on
344
either <a class="reference internal" href="core/connections.html#sqlalchemy.engine.Connection" title="sqlalchemy.engine.Connection"><tt class="xref py py-class docutils literal"><span class="pre">Connection</span></tt></a> or the proxied connection, which will de-associate
345
the connection from the pool such that it will be closed and discarded
346
when <a class="reference internal" href="core/connections.html#sqlalchemy.engine.Connection.close" title="sqlalchemy.engine.Connection.close"><tt class="xref py py-meth docutils literal"><span class="pre">Connection.close()</span></tt></a> is called:</p>
347
<div class="highlight-python"><pre>conn = engine.connect()
348
conn.detach() # detaches the DBAPI connection from the connection pool
349
conn.connection.<go nuts>
350
conn.close() # connection is closed for real, the pool replaces it with a new connection</pre>
354
<div class="section" id="metadata-schema">
355
<h2>MetaData / Schema<a class="headerlink" href="#metadata-schema" title="Permalink to this headline">¶</a></h2>
356
<div class="section" id="my-program-is-hanging-when-i-say-table-drop-metadata-drop-all">
357
<h3>My program is hanging when I say <tt class="docutils literal"><span class="pre">table.drop()</span></tt> / <tt class="docutils literal"><span class="pre">metadata.drop_all()</span></tt><a class="headerlink" href="#my-program-is-hanging-when-i-say-table-drop-metadata-drop-all" title="Permalink to this headline">¶</a></h3>
358
<p>This usually corresponds to two conditions: 1. using PostgreSQL, which is really
359
strict about table locks, and 2. you have a connection still open which
360
contains locks on the table and is distinct from the connection being used for
361
the DROP statement. Heres the most minimal version of the pattern:</p>
362
<div class="highlight-python"><div class="highlight"><pre><span class="n">connection</span> <span class="o">=</span> <span class="n">engine</span><span class="o">.</span><span class="n">connect</span><span class="p">()</span>
363
<span class="n">result</span> <span class="o">=</span> <span class="n">connection</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">mytable</span><span class="o">.</span><span class="n">select</span><span class="p">())</span>
365
<span class="n">mytable</span><span class="o">.</span><span class="n">drop</span><span class="p">(</span><span class="n">engine</span><span class="p">)</span></pre></div>
367
<p>Above, a connection pool connection is still checked out; furthermore, the
368
result object above also maintains a link to this connection. If
369
“implicit execution” is used, the result will hold this connection opened until
370
the result object is closed or all rows are exhausted.</p>
371
<p>The call to <tt class="docutils literal"><span class="pre">mytable.drop(engine)</span></tt> attempts to emit DROP TABLE on a second
372
connection procured from the <a class="reference internal" href="core/connections.html#sqlalchemy.engine.Engine" title="sqlalchemy.engine.Engine"><tt class="xref py py-class docutils literal"><span class="pre">Engine</span></tt></a> which will lock.</p>
373
<p>The solution is to close out all connections before emitting DROP TABLE:</p>
374
<div class="highlight-python"><div class="highlight"><pre><span class="n">connection</span> <span class="o">=</span> <span class="n">engine</span><span class="o">.</span><span class="n">connect</span><span class="p">()</span>
375
<span class="n">result</span> <span class="o">=</span> <span class="n">connection</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">mytable</span><span class="o">.</span><span class="n">select</span><span class="p">())</span>
377
<span class="c"># fully read result sets</span>
378
<span class="n">result</span><span class="o">.</span><span class="n">fetchall</span><span class="p">()</span>
380
<span class="c"># close connections</span>
381
<span class="n">connection</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
383
<span class="c"># now locks are removed</span>
384
<span class="n">mytable</span><span class="o">.</span><span class="n">drop</span><span class="p">(</span><span class="n">engine</span><span class="p">)</span></pre></div>
387
<div class="section" id="does-sqlalchemy-support-alter-table-create-view-create-trigger-schema-upgrade-functionality">
388
<h3>Does SQLAlchemy support ALTER TABLE, CREATE VIEW, CREATE TRIGGER, Schema Upgrade Functionality?<a class="headerlink" href="#does-sqlalchemy-support-alter-table-create-view-create-trigger-schema-upgrade-functionality" title="Permalink to this headline">¶</a></h3>
389
<p>General ALTER support isn’t present in SQLAlchemy directly. For special DDL
390
on an ad-hoc basis, the <a class="reference internal" href="core/ddl.html#sqlalchemy.schema.DDL" title="sqlalchemy.schema.DDL"><tt class="xref py py-class docutils literal"><span class="pre">DDL</span></tt></a> and related constructs can be used.
391
See <a class="reference internal" href="core/ddl.html"><em>Customizing DDL</em></a> for a discussion on this subject.</p>
392
<p>A more comprehensive option is to use schema migration tools, such as Alembic
393
or SQLAlchemy-Migrate; see <a class="reference internal" href="core/metadata.html#schema-migrations"><em>Altering Schemas through Migrations</em></a> for discussion on this.</p>
395
<div class="section" id="how-can-i-sort-table-objects-in-order-of-their-dependency">
396
<h3>How can I sort Table objects in order of their dependency?<a class="headerlink" href="#how-can-i-sort-table-objects-in-order-of-their-dependency" title="Permalink to this headline">¶</a></h3>
397
<p>This is available via the <a class="reference internal" href="core/metadata.html#sqlalchemy.schema.MetaData.sorted_tables" title="sqlalchemy.schema.MetaData.sorted_tables"><tt class="xref py py-attr docutils literal"><span class="pre">MetaData.sorted_tables</span></tt></a> function:</p>
398
<div class="highlight-python"><pre>metadata = MetaData()
399
# ... add Table objects to metadata
400
ti = metadata.sorted_tables:
405
<div class="section" id="how-can-i-get-the-create-table-drop-table-output-as-a-string">
406
<h3>How can I get the CREATE TABLE/ DROP TABLE output as a string?<a class="headerlink" href="#how-can-i-get-the-create-table-drop-table-output-as-a-string" title="Permalink to this headline">¶</a></h3>
407
<p>Modern SQLAlchemy has clause constructs which represent DDL operations. These
408
can be rendered to strings like any other SQL expression:</p>
409
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">sqlalchemy.schema</span> <span class="kn">import</span> <span class="n">CreateTable</span>
411
<span class="k">print</span> <span class="n">CreateTable</span><span class="p">(</span><span class="n">mytable</span><span class="p">)</span></pre></div>
413
<p>To get the string specific to a certain engine:</p>
414
<div class="highlight-python"><div class="highlight"><pre><span class="k">print</span> <span class="n">CreateTable</span><span class="p">(</span><span class="n">mytable</span><span class="p">)</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">engine</span><span class="p">)</span></pre></div>
416
<p>There’s also a special form of <a class="reference internal" href="core/connections.html#sqlalchemy.engine.Engine" title="sqlalchemy.engine.Engine"><tt class="xref py py-class docutils literal"><span class="pre">Engine</span></tt></a> that can let you dump an entire
417
metadata creation sequence, using this recipe:</p>
418
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">dump</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="o">*</span><span class="n">multiparams</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">):</span>
419
<span class="k">print</span> <span class="n">sql</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">dialect</span><span class="o">=</span><span class="n">engine</span><span class="o">.</span><span class="n">dialect</span><span class="p">)</span>
420
<span class="n">engine</span> <span class="o">=</span> <span class="n">create_engine</span><span class="p">(</span><span class="s">'postgresql://'</span><span class="p">,</span> <span class="n">strategy</span><span class="o">=</span><span class="s">'mock'</span><span class="p">,</span> <span class="n">executor</span><span class="o">=</span><span class="n">dump</span><span class="p">)</span>
421
<span class="n">metadata</span><span class="o">.</span><span class="n">create_all</span><span class="p">(</span><span class="n">engine</span><span class="p">,</span> <span class="n">checkfirst</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span></pre></div>
423
<p>The <a class="reference external" href="https://bitbucket.org/zzzeek/alembic">Alembic</a> tool also supports
424
an “offline” SQL generation mode that renders database migrations as SQL scripts.</p>
426
<div class="section" id="how-can-i-subclass-table-column-to-provide-certain-behaviors-configurations">
427
<h3>How can I subclass Table/Column to provide certain behaviors/configurations?<a class="headerlink" href="#how-can-i-subclass-table-column-to-provide-certain-behaviors-configurations" title="Permalink to this headline">¶</a></h3>
428
<p><a class="reference internal" href="core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> and <a class="reference internal" href="core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> are not good targets for direct subclassing.
429
However, there are simple ways to get on-construction behaviors using creation
430
functions, and behaviors related to the linkages between schema objects such as
431
constraint conventions or naming conventions using attachment events.
432
An example of many of these
433
techniques can be seen at <a class="reference external" href="http://www.sqlalchemy.org/trac/wiki/UsageRecipes/NamingConventions">Naming Conventions</a>.</p>
436
<div class="section" id="sql-expressions">
437
<h2>SQL Expressions<a class="headerlink" href="#sql-expressions" title="Permalink to this headline">¶</a></h2>
438
<div class="section" id="why-does-col-in-produce-col-col-why-not-1-0">
439
<h3>Why does <tt class="docutils literal"><span class="pre">.col.in_([])</span></tt> Produce <tt class="docutils literal"><span class="pre">col</span> <span class="pre">!=</span> <span class="pre">col</span></tt>? Why not <tt class="docutils literal"><span class="pre">1=0</span></tt>?<a class="headerlink" href="#why-does-col-in-produce-col-col-why-not-1-0" title="Permalink to this headline">¶</a></h3>
440
<p>A little introduction to the issue. The IN operator in SQL, given a list of
441
elements to compare against a column, generally does not accept an empty list,
442
that is while it is valid to say:</p>
443
<div class="highlight-python"><pre>column IN (1, 2, 3)</pre>
445
<p>it’s not valid to say:</p>
446
<div class="highlight-python"><pre>column IN ()</pre>
448
<p>SQLAlchemy’s <tt class="xref py py-meth docutils literal"><span class="pre">Operators.in_()</span></tt> operator, when given an empty list, produces this
450
<div class="highlight-python"><div class="highlight"><pre><span class="n">column</span> <span class="o">!=</span> <span class="n">column</span></pre></div>
452
<p>As of version 0.6, it also produces a warning stating that a less efficient
453
comparison operation will be rendered. This expression is the only one that is
454
both database agnostic and produces correct results.</p>
455
<p>For example, the naive approach of “just evaluate to false, by comparing 1=0
456
or 1!=1”, does not handle nulls properly. An expression like:</p>
457
<div class="highlight-python"><pre>NOT column != column</pre>
459
<p>will not return a row when “column” is null, but an expression which does not
460
take the column into account:</p>
461
<div class="highlight-python"><pre>NOT 1=0</pre>
464
<p>Closer to the mark is the following CASE expression:</p>
465
<div class="highlight-python"><pre>CASE WHEN column IS NOT NULL THEN 1=0 ELSE NULL END</pre>
467
<p>We don’t use this expression due to its verbosity, and its also not
468
typically accepted by Oracle within a WHERE clause - depending
469
on how you phrase it, you’ll either get “ORA-00905: missing keyword” or
470
“ORA-00920: invalid relational operator”. It’s also still less efficient than
471
just rendering SQL without the clause altogether (or not issuing the SQL at
472
all, if the statement is just a simple search).</p>
473
<p>The best approach therefore is to avoid the usage of IN given an argument list
474
of zero length. Instead, don’t emit the Query in the first place, if no rows
475
should be returned. The warning is best promoted to a full error condition
476
using the Python warnings filter (see <a class="reference external" href="http://docs.python.org/library/warnings.html">http://docs.python.org/library/warnings.html</a>).</p>
479
<div class="section" id="orm-configuration">
480
<h2>ORM Configuration<a class="headerlink" href="#orm-configuration" title="Permalink to this headline">¶</a></h2>
481
<div class="section" id="how-do-i-map-a-table-that-has-no-primary-key">
482
<h3>How do I map a table that has no primary key?<a class="headerlink" href="#how-do-i-map-a-table-that-has-no-primary-key" title="Permalink to this headline">¶</a></h3>
483
<p>In almost all cases, a table does have a so-called <em class="xref std std-term">candidate key</em>, which is a column or series
484
of columns that uniquely identify a row. If a table truly doesn’t have this, and has actual
485
fully duplicate rows, the table is not corresponding to <a class="reference external" href="http://en.wikipedia.org/wiki/First_normal_form">first normal form</a> and cannot be mapped. Otherwise, whatever columns comprise the best candidate key can be
486
applied directly to the mapper:</p>
487
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">SomeClass</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
488
<span class="n">__table__</span> <span class="o">=</span> <span class="n">some_table_with_no_pk</span>
489
<span class="n">__mapper_args__</span> <span class="o">=</span> <span class="p">{</span>
490
<span class="s">'primary_key'</span><span class="p">:[</span><span class="n">some_table_with_no_pk</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">uid</span><span class="p">,</span> <span class="n">some_table_with_no_pk</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">bar</span><span class="p">]</span>
491
<span class="p">}</span></pre></div>
493
<p>Better yet is when using fully declared table metadata, use the <tt class="docutils literal"><span class="pre">primary_key=True</span></tt>
494
flag on those columns:</p>
495
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">SomeClass</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
496
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s">"some_table_with_no_pk"</span>
498
<span class="n">uid</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>
499
<span class="n">bar</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="n">String</span><span class="p">,</span> <span class="n">primary_key</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span></pre></div>
501
<p>All tables in a relational database should have primary keys. Even a many-to-many
502
association table - the primary key would be the composite of the two association
504
<div class="highlight-python"><pre>CREATE TABLE my_association (
505
user_id INTEGER REFERENCES user(id),
506
account_id INTEGER REFERENCES account(id),
507
PRIMARY KEY (user_id, account_id)
511
<div class="section" id="how-do-i-configure-a-column-that-is-a-python-reserved-word-or-similar">
512
<h3>How do I configure a Column that is a Python reserved word or similar?<a class="headerlink" href="#how-do-i-configure-a-column-that-is-a-python-reserved-word-or-similar" title="Permalink to this headline">¶</a></h3>
513
<p>Column-based attributes can be given any name desired in the mapping. See
514
<a class="reference internal" href="orm/mapper_config.html#mapper-column-distinct-names"><em>Naming Columns Distinctly from Attribute Names</em></a>.</p>
516
<div class="section" id="how-do-i-get-a-list-of-all-columns-relationships-mapped-attributes-etc-given-a-mapped-class">
517
<h3>How do I get a list of all columns, relationships, mapped attributes, etc. given a mapped class?<a class="headerlink" href="#how-do-i-get-a-list-of-all-columns-relationships-mapped-attributes-etc-given-a-mapped-class" title="Permalink to this headline">¶</a></h3>
518
<p>This information is all available from the <a class="reference internal" href="orm/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> object.</p>
519
<p>To get at the <a class="reference internal" href="orm/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> for a particular mapped class, call the
520
<a class="reference internal" href="core/inspection.html#sqlalchemy.inspection.inspect" title="sqlalchemy.inspection.inspect"><tt class="xref py py-func docutils literal"><span class="pre">inspect()</span></tt></a> function on it:</p>
521
<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">inspect</span>
523
<span class="n">mapper</span> <span class="o">=</span> <span class="n">inspect</span><span class="p">(</span><span class="n">MyClass</span><span class="p">)</span></pre></div>
525
<p>From there, all information about the class can be acquired using such methods as:</p>
527
<li><a class="reference internal" href="orm/mapper_config.html#sqlalchemy.orm.mapper.Mapper.attrs" title="sqlalchemy.orm.mapper.Mapper.attrs"><tt class="xref py py-attr docutils literal"><span class="pre">Mapper.attrs</span></tt></a> - a namespace of all mapped attributes. The attributes
528
themselves are instances of <a class="reference internal" href="orm/internals.html#sqlalchemy.orm.interfaces.MapperProperty" title="sqlalchemy.orm.interfaces.MapperProperty"><tt class="xref py py-class docutils literal"><span class="pre">MapperProperty</span></tt></a>, which contain additional
529
attributes that can lead to the mapped SQL expression or column, if applicable.</li>
530
<li><a class="reference internal" href="orm/mapper_config.html#sqlalchemy.orm.mapper.Mapper.column_attrs" title="sqlalchemy.orm.mapper.Mapper.column_attrs"><tt class="xref py py-attr docutils literal"><span class="pre">Mapper.column_attrs</span></tt></a> - the mapped attribute namespace
531
limited to column and SQL expression attributes. You might want to use
532
<a class="reference internal" href="orm/mapper_config.html#sqlalchemy.orm.mapper.Mapper.columns" title="sqlalchemy.orm.mapper.Mapper.columns"><tt class="xref py py-attr docutils literal"><span class="pre">Mapper.columns</span></tt></a> to get at the <a class="reference internal" href="core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> objects directly.</li>
533
<li><a class="reference internal" href="orm/mapper_config.html#sqlalchemy.orm.mapper.Mapper.relationships" title="sqlalchemy.orm.mapper.Mapper.relationships"><tt class="xref py py-attr docutils literal"><span class="pre">Mapper.relationships</span></tt></a> - namespace of all <a class="reference internal" href="orm/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> attributes.</li>
534
<li><a class="reference internal" href="orm/mapper_config.html#sqlalchemy.orm.mapper.Mapper.all_orm_descriptors" title="sqlalchemy.orm.mapper.Mapper.all_orm_descriptors"><tt class="xref py py-attr docutils literal"><span class="pre">Mapper.all_orm_descriptors</span></tt></a> - namespace of all mapped attributes, plus user-defined
535
attributes defined using systems such as <a class="reference internal" href="orm/extensions/hybrid.html#sqlalchemy.ext.hybrid.hybrid_property" title="sqlalchemy.ext.hybrid.hybrid_property"><tt class="xref py py-class docutils literal"><span class="pre">hybrid_property</span></tt></a>, <a class="reference internal" href="orm/extensions/associationproxy.html#sqlalchemy.ext.associationproxy.AssociationProxy" title="sqlalchemy.ext.associationproxy.AssociationProxy"><tt class="xref py py-class docutils literal"><span class="pre">AssociationProxy</span></tt></a> and others.</li>
536
<li><a class="reference internal" href="orm/mapper_config.html#sqlalchemy.orm.mapper.Mapper.columns" title="sqlalchemy.orm.mapper.Mapper.columns"><tt class="xref py py-attr docutils literal"><span class="pre">Mapper.columns</span></tt></a> - A namespace of <a class="reference internal" href="core/metadata.html#sqlalchemy.schema.Column" title="sqlalchemy.schema.Column"><tt class="xref py py-class docutils literal"><span class="pre">Column</span></tt></a> objects and other named
537
SQL expressions associated with the mapping.</li>
538
<li><a class="reference internal" href="orm/mapper_config.html#sqlalchemy.orm.mapper.Mapper.mapped_table" title="sqlalchemy.orm.mapper.Mapper.mapped_table"><tt class="xref py py-attr docutils literal"><span class="pre">Mapper.mapped_table</span></tt></a> - The <a class="reference internal" href="core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> or other selectable to which
539
this mapper is mapped.</li>
540
<li><a class="reference internal" href="orm/mapper_config.html#sqlalchemy.orm.mapper.Mapper.local_table" title="sqlalchemy.orm.mapper.Mapper.local_table"><tt class="xref py py-attr docutils literal"><span class="pre">Mapper.local_table</span></tt></a> - The <a class="reference internal" href="core/metadata.html#sqlalchemy.schema.Table" title="sqlalchemy.schema.Table"><tt class="xref py py-class docutils literal"><span class="pre">Table</span></tt></a> that is “local” to this mapper;
541
this differs from <a class="reference internal" href="orm/mapper_config.html#sqlalchemy.orm.mapper.Mapper.mapped_table" title="sqlalchemy.orm.mapper.Mapper.mapped_table"><tt class="xref py py-attr docutils literal"><span class="pre">Mapper.mapped_table</span></tt></a> in the case of a mapper mapped
542
using inheritance to a composed selectable.</li>
545
<div class="section" id="i-m-using-declarative-and-setting-primaryjoin-secondaryjoin-using-an-and-or-or-and-i-am-getting-an-error-message-about-foreign-keys">
546
<h3>I’m using Declarative and setting primaryjoin/secondaryjoin using an <tt class="docutils literal"><span class="pre">and_()</span></tt> or <tt class="docutils literal"><span class="pre">or_()</span></tt>, and I am getting an error message about foreign keys.<a class="headerlink" href="#i-m-using-declarative-and-setting-primaryjoin-secondaryjoin-using-an-and-or-or-and-i-am-getting-an-error-message-about-foreign-keys" title="Permalink to this headline">¶</a></h3>
547
<p>Are you doing this?:</p>
548
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">MyClass</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
549
<span class="c"># ....</span>
551
<span class="n">foo</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="s">"Dest"</span><span class="p">,</span> <span class="n">primaryjoin</span><span class="o">=</span><span class="n">and_</span><span class="p">(</span><span class="s">"MyClass.id==Dest.foo_id"</span><span class="p">,</span> <span class="s">"MyClass.foo==Dest.bar"</span><span class="p">))</span></pre></div>
553
<p>That’s an <tt class="docutils literal"><span class="pre">and_()</span></tt> of two string expressions, which SQLAlchemy cannot apply any mapping towards. Declarative allows <a class="reference internal" href="orm/relationships.html#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> arguments to be specified as strings, which are converted into expression objects using <tt class="docutils literal"><span class="pre">eval()</span></tt>. But this doesn’t occur inside of an <tt class="docutils literal"><span class="pre">and_()</span></tt> expression - it’s a special operation declarative applies only to the <em>entirety</em> of what’s passed to primaryjoin or other arguments as a string:</p>
554
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">MyClass</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
555
<span class="c"># ....</span>
557
<span class="n">foo</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="s">"Dest"</span><span class="p">,</span> <span class="n">primaryjoin</span><span class="o">=</span><span class="s">"and_(MyClass.id==Dest.foo_id, MyClass.foo==Dest.bar)"</span><span class="p">)</span></pre></div>
559
<p>Or if the objects you need are already available, skip the strings:</p>
560
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">MyClass</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
561
<span class="c"># ....</span>
563
<span class="n">foo</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="n">Dest</span><span class="p">,</span> <span class="n">primaryjoin</span><span class="o">=</span><span class="n">and_</span><span class="p">(</span><span class="n">MyClass</span><span class="o">.</span><span class="n">id</span><span class="o">==</span><span class="n">Dest</span><span class="o">.</span><span class="n">foo_id</span><span class="p">,</span> <span class="n">MyClass</span><span class="o">.</span><span class="n">foo</span><span class="o">==</span><span class="n">Dest</span><span class="o">.</span><span class="n">bar</span><span class="p">))</span></pre></div>
565
<p>The same idea applies to all the other arguments, such as <tt class="docutils literal"><span class="pre">foreign_keys</span></tt>:</p>
566
<div class="highlight-python"><div class="highlight"><pre><span class="c"># wrong !</span>
567
<span class="n">foo</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="n">Dest</span><span class="p">,</span> <span class="n">foreign_keys</span><span class="o">=</span><span class="p">[</span><span class="s">"Dest.foo_id"</span><span class="p">,</span> <span class="s">"Dest.bar_id"</span><span class="p">])</span>
569
<span class="c"># correct !</span>
570
<span class="n">foo</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="n">Dest</span><span class="p">,</span> <span class="n">foreign_keys</span><span class="o">=</span><span class="s">"[Dest.foo_id, Dest.bar_id]"</span><span class="p">)</span>
572
<span class="c"># also correct !</span>
573
<span class="n">foo</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="n">Dest</span><span class="p">,</span> <span class="n">foreign_keys</span><span class="o">=</span><span class="p">[</span><span class="n">Dest</span><span class="o">.</span><span class="n">foo_id</span><span class="p">,</span> <span class="n">Dest</span><span class="o">.</span><span class="n">bar_id</span><span class="p">])</span>
575
<span class="c"># if you're using columns from the class that you're inside of, just use the column objects !</span>
576
<span class="k">class</span> <span class="nc">MyClass</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
577
<span class="n">foo_id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
578
<span class="n">bar_id</span> <span class="o">=</span> <span class="n">Column</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
579
<span class="c"># ...</span>
581
<span class="n">foo</span> <span class="o">=</span> <span class="n">relationship</span><span class="p">(</span><span class="n">Dest</span><span class="p">,</span> <span class="n">foreign_keys</span><span class="o">=</span><span class="p">[</span><span class="n">foo_id</span><span class="p">,</span> <span class="n">bar_id</span><span class="p">])</span></pre></div>
585
<div class="section" id="sessions-queries">
586
<h2>Sessions / Queries<a class="headerlink" href="#sessions-queries" title="Permalink to this headline">¶</a></h2>
587
<div class="section" id="this-session-s-transaction-has-been-rolled-back-due-to-a-previous-exception-during-flush-or-similar">
588
<h3>“This Session’s transaction has been rolled back due to a previous exception during flush.” (or similar)<a class="headerlink" href="#this-session-s-transaction-has-been-rolled-back-due-to-a-previous-exception-during-flush-or-similar" title="Permalink to this headline">¶</a></h3>
589
<p>This is an error that occurs when a <a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session.flush" title="sqlalchemy.orm.session.Session.flush"><tt class="xref py py-meth docutils literal"><span class="pre">Session.flush()</span></tt></a> raises an exception, rolls back
590
the transaction, but further commands upon the <cite>Session</cite> are called without an
591
explicit call to <a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session.rollback" title="sqlalchemy.orm.session.Session.rollback"><tt class="xref py py-meth docutils literal"><span class="pre">Session.rollback()</span></tt></a> or <a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session.close" title="sqlalchemy.orm.session.Session.close"><tt class="xref py py-meth docutils literal"><span class="pre">Session.close()</span></tt></a>.</p>
592
<p>It usually corresponds to an application that catches an exception
593
upon <a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session.flush" title="sqlalchemy.orm.session.Session.flush"><tt class="xref py py-meth docutils literal"><span class="pre">Session.flush()</span></tt></a> or <a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session.commit" title="sqlalchemy.orm.session.Session.commit"><tt class="xref py py-meth docutils literal"><span class="pre">Session.commit()</span></tt></a> and
594
does not properly handle the exception. For example:</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">create_engine</span><span class="p">,</span> <span class="n">Column</span><span class="p">,</span> <span class="n">Integer</span>
596
<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="n">sessionmaker</span>
597
<span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span> <span class="n">declarative_base</span>
599
<span class="n">Base</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">(</span><span class="n">create_engine</span><span class="p">(</span><span class="s">'sqlite://'</span><span class="p">))</span>
601
<span class="k">class</span> <span class="nc">Foo</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">'foo'</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>
605
<span class="n">Base</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">create_all</span><span class="p">()</span>
607
<span class="n">session</span> <span class="o">=</span> <span class="n">sessionmaker</span><span class="p">()()</span>
609
<span class="c"># constraint violation</span>
610
<span class="n">session</span><span class="o">.</span><span class="n">add_all</span><span class="p">([</span><span class="n">Foo</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">),</span> <span class="n">Foo</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="mi">1</span><span class="p">)])</span>
612
<span class="k">try</span><span class="p">:</span>
613
<span class="n">session</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
614
<span class="k">except</span><span class="p">:</span>
615
<span class="c"># ignore error</span>
616
<span class="k">pass</span>
618
<span class="c"># continue using session without rolling back</span>
619
<span class="n">session</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span></pre></div>
621
<p>The usage of the <a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session" title="sqlalchemy.orm.session.Session"><tt class="xref py py-class docutils literal"><span class="pre">Session</span></tt></a> should fit within a structure similar to this:</p>
622
<div class="highlight-python"><pre>try:
629
session.close() # optional, depends on use case</pre>
631
<p>Many things can cause a failure within the try/except besides flushes. You
632
should always have some kind of “framing” of your session operations so that
633
connection and transaction resources have a definitive boundary, otherwise
634
your application doesn’t really have its usage of resources under control.
635
This is not to say that you need to put try/except blocks all throughout your
636
application - on the contrary, this would be a terrible idea. You should
637
architect your application such that there is one (or few) point(s) of
638
“framing” around session operations.</p>
639
<p>For a detailed discussion on how to organize usage of the <a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session" title="sqlalchemy.orm.session.Session"><tt class="xref py py-class docutils literal"><span class="pre">Session</span></tt></a>,
640
please see <a class="reference internal" href="orm/session.html#session-faq-whentocreate"><em>When do I construct a Session, when do I commit it, and when do I close it?</em></a>.</p>
641
<div class="section" id="but-why-does-flush-insist-on-issuing-a-rollback">
642
<h4>But why does flush() insist on issuing a ROLLBACK?<a class="headerlink" href="#but-why-does-flush-insist-on-issuing-a-rollback" title="Permalink to this headline">¶</a></h4>
643
<p>It would be great if <a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session.flush" title="sqlalchemy.orm.session.Session.flush"><tt class="xref py py-meth docutils literal"><span class="pre">Session.flush()</span></tt></a> could partially complete and then not roll
644
back, however this is beyond its current capabilities since its internal
645
bookkeeping would have to be modified such that it can be halted at any time
646
and be exactly consistent with what’s been flushed to the database. While this
647
is theoretically possible, the usefulness of the enhancement is greatly
648
decreased by the fact that many database operations require a ROLLBACK in any
649
case. Postgres in particular has operations which, once failed, the
650
transaction is not allowed to continue:</p>
651
<div class="highlight-python"><pre>test=> create table foo(id integer primary key);
652
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
656
test=> insert into foo values(1);
662
test=> insert into foo values(1);
663
ERROR: duplicate key value violates unique constraint "foo_pkey"
664
test=> insert into foo values(2);
665
ERROR: current transaction is aborted, commands ignored until end of transaction block</pre>
667
<p>What SQLAlchemy offers that solves both issues is support of SAVEPOINT, via
668
<a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session.begin_nested" title="sqlalchemy.orm.session.Session.begin_nested"><tt class="xref py py-meth docutils literal"><span class="pre">Session.begin_nested()</span></tt></a>. Using <a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session.begin_nested" title="sqlalchemy.orm.session.Session.begin_nested"><tt class="xref py py-meth docutils literal"><span class="pre">Session.begin_nested()</span></tt></a>, you can frame an operation that may
669
potentially fail within a transaction, and then “roll back” to the point
670
before its failure while maintaining the enclosing transaction.</p>
672
<div class="section" id="but-why-isn-t-the-one-automatic-call-to-rollback-enough-why-must-i-rollback-again">
673
<h4>But why isn’t the one automatic call to ROLLBACK enough? Why must I ROLLBACK again?<a class="headerlink" href="#but-why-isn-t-the-one-automatic-call-to-rollback-enough-why-must-i-rollback-again" title="Permalink to this headline">¶</a></h4>
674
<p>This is again a matter of the <a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session" title="sqlalchemy.orm.session.Session"><tt class="xref py py-class docutils literal"><span class="pre">Session</span></tt></a> providing a consistent interface and
675
refusing to guess about what context its being used. For example, the
676
<a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session" title="sqlalchemy.orm.session.Session"><tt class="xref py py-class docutils literal"><span class="pre">Session</span></tt></a> supports “framing” above within multiple levels. Such as, suppose
677
you had a decorator <tt class="docutils literal"><span class="pre">@with_session()</span></tt>, which did this:</p>
678
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">with_session</span><span class="p">(</span><span class="n">fn</span><span class="p">):</span>
679
<span class="k">def</span> <span class="nf">go</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
680
<span class="n">session</span><span class="o">.</span><span class="n">begin</span><span class="p">(</span><span class="n">subtransactions</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
681
<span class="k">try</span><span class="p">:</span>
682
<span class="n">ret</span> <span class="o">=</span> <span class="n">fn</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">)</span>
683
<span class="n">session</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
684
<span class="k">return</span> <span class="n">ret</span>
685
<span class="k">except</span><span class="p">:</span>
686
<span class="n">session</span><span class="o">.</span><span class="n">rollback</span><span class="p">()</span>
687
<span class="k">raise</span>
688
<span class="k">return</span> <span class="n">go</span></pre></div>
690
<p>The above decorator begins a transaction if one does not exist already, and
691
then commits it, if it were the creator. The “subtransactions” flag means that
692
if <a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session.begin" title="sqlalchemy.orm.session.Session.begin"><tt class="xref py py-meth docutils literal"><span class="pre">Session.begin()</span></tt></a> were already called by an enclosing function, nothing happens
693
except a counter is incremented - this counter is decremented when <a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session.commit" title="sqlalchemy.orm.session.Session.commit"><tt class="xref py py-meth docutils literal"><span class="pre">Session.commit()</span></tt></a>
694
is called and only when it goes back to zero does the actual COMMIT happen. It
695
allows this usage pattern:</p>
696
<div class="highlight-python"><pre>@with_session
710
<p><tt class="docutils literal"><span class="pre">one()</span></tt> can call <tt class="docutils literal"><span class="pre">two()</span></tt>, or <tt class="docutils literal"><span class="pre">two()</span></tt> can be called by itself, and the
711
<tt class="docutils literal"><span class="pre">@with_session</span></tt> decorator ensures the appropriate “framing” - the transaction
712
boundaries stay on the outermost call level. As you can see, if <tt class="docutils literal"><span class="pre">two()</span></tt> calls
713
<tt class="docutils literal"><span class="pre">flush()</span></tt> which throws an exception and then issues a <tt class="docutils literal"><span class="pre">rollback()</span></tt>, there will
714
<em>always</em> be a second <tt class="docutils literal"><span class="pre">rollback()</span></tt> performed by the decorator, and possibly a
715
third corresponding to two levels of decorator. If the <tt class="docutils literal"><span class="pre">flush()</span></tt> pushed the
716
<tt class="docutils literal"><span class="pre">rollback()</span></tt> all the way out to the top of the stack, and then we said that
717
all remaining <tt class="docutils literal"><span class="pre">rollback()</span></tt> calls are moot, there is some silent behavior going
718
on there. A poorly written enclosing method might suppress the exception, and
719
then call <tt class="docutils literal"><span class="pre">commit()</span></tt> assuming nothing is wrong, and then you have a silent
720
failure condition. The main reason people get this error in fact is because
721
they didn’t write clean “framing” code and they would have had other problems
723
<p>If you think the above use case is a little exotic, the same kind of thing
724
comes into play if you want to SAVEPOINT- you might call <tt class="docutils literal"><span class="pre">begin_nested()</span></tt>
725
several times, and the <tt class="docutils literal"><span class="pre">commit()</span></tt>/<tt class="docutils literal"><span class="pre">rollback()</span></tt> calls each resolve the most
726
recent <tt class="docutils literal"><span class="pre">begin_nested()</span></tt>. The meaning of <tt class="docutils literal"><span class="pre">rollback()</span></tt> or <tt class="docutils literal"><span class="pre">commit()</span></tt> is
727
dependent upon which enclosing block it is called, and you might have any
728
sequence of <tt class="docutils literal"><span class="pre">rollback()</span></tt>/<tt class="docutils literal"><span class="pre">commit()</span></tt> in any order, and its the level of nesting
729
that determines their behavior.</p>
730
<p>In both of the above cases, if <tt class="docutils literal"><span class="pre">flush()</span></tt> broke the nesting of transaction
731
blocks, the behavior is, depending on scenario, anywhere from “magic” to
732
silent failure to blatant interruption of code flow.</p>
733
<p><tt class="docutils literal"><span class="pre">flush()</span></tt> makes its own “subtransaction”, so that a transaction is started up
734
regardless of the external transactional state, and when complete it calls
735
<tt class="docutils literal"><span class="pre">commit()</span></tt>, or <tt class="docutils literal"><span class="pre">rollback()</span></tt> upon failure - but that <tt class="docutils literal"><span class="pre">rollback()</span></tt> corresponds
736
to its own subtransaction - it doesn’t want to guess how you’d like to handle
737
the external “framing” of the transaction, which could be nested many levels
738
with any combination of subtransactions and real SAVEPOINTs. The job of
739
starting/ending the “frame” is kept consistently with the code external to the
740
<tt class="docutils literal"><span class="pre">flush()</span></tt>, and we made a decision that this was the most consistent approach.</p>
743
<div class="section" id="i-m-inserting-400-000-rows-with-the-orm-and-it-s-really-slow">
744
<h3>I’m inserting 400,000 rows with the ORM and it’s really slow!<a class="headerlink" href="#i-m-inserting-400-000-rows-with-the-orm-and-it-s-really-slow" title="Permalink to this headline">¶</a></h3>
745
<p>The SQLAlchemy ORM uses the <a class="reference internal" href="glossary.html#term-unit-of-work"><em class="xref std std-term">unit of work</em></a> pattern when synchronizing
746
changes to the database. This pattern goes far beyond simple “inserts”
747
of data. It includes that attributes which are assigned on objects are
748
received using an attribute instrumentation system which tracks
749
changes on objects as they are made, includes that all rows inserted
750
are tracked in an identity map which has the effect that for each row
751
SQLAlchemy must retrieve its “last inserted id” if not already given,
752
and also involves that rows to be inserted are scanned and sorted for
753
dependencies as needed. Objects are also subject to a fair degree of
754
bookkeeping in order to keep all of this running, which for a very
755
large number of rows at once can create an inordinate amount of time
756
spent with large data structures, hence it’s best to chunk these.</p>
757
<p>Basically, unit of work is a large degree of automation in order to
758
automate the task of persisting a complex object graph into a
759
relational database with no explicit persistence code, and this
760
automation has a price.</p>
761
<p>ORMs are basically not intended for high-performance bulk inserts -
762
this is the whole reason SQLAlchemy offers the Core in addition to the
763
ORM as a first-class component.</p>
764
<p>For the use case of fast bulk inserts, the
765
SQL generation and execution system that the ORM builds on top of
766
is part of the Core. Using this system directly, we can produce an INSERT that
767
is competitive with using the raw database API directly.</p>
768
<p>The example below illustrates time-based tests for four different
769
methods of inserting rows, going from the most automated to the least.
770
With cPython 2.7, runtimes observed:</p>
771
<div class="highlight-python"><pre>classics-MacBook-Pro:sqlalchemy classic$ python test.py
772
SQLAlchemy ORM: Total time for 100000 records 14.3528850079 secs
773
SQLAlchemy ORM pk given: Total time for 100000 records 10.0164160728 secs
774
SQLAlchemy Core: Total time for 100000 records 0.775382995605 secs
775
sqlite3: Total time for 100000 records 0.676795005798 sec</pre>
777
<p>We can reduce the time by a factor of three using recent versions of <a class="reference external" href="http://pypy.org/">Pypy</a>:</p>
778
<div class="highlight-python"><pre>classics-MacBook-Pro:sqlalchemy classic$ /usr/local/src/pypy-2.1-beta2-osx64/bin/pypy test.py
779
SQLAlchemy ORM: Total time for 100000 records 5.88369488716 secs
780
SQLAlchemy ORM pk given: Total time for 100000 records 3.52294301987 secs
781
SQLAlchemy Core: Total time for 100000 records 0.613556146622 secs
782
sqlite3: Total time for 100000 records 0.442467927933 sec</pre>
785
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">time</span>
786
<span class="kn">import</span> <span class="nn">sqlite3</span>
788
<span class="kn">from</span> <span class="nn">sqlalchemy.ext.declarative</span> <span class="kn">import</span> <span class="n">declarative_base</span>
789
<span class="kn">from</span> <span class="nn">sqlalchemy</span> <span class="kn">import</span> <span class="n">Column</span><span class="p">,</span> <span class="n">Integer</span><span class="p">,</span> <span class="n">String</span><span class="p">,</span> <span class="n">create_engine</span>
790
<span class="kn">from</span> <span class="nn">sqlalchemy.orm</span> <span class="kn">import</span> <span class="n">scoped_session</span><span class="p">,</span> <span class="n">sessionmaker</span>
792
<span class="n">Base</span> <span class="o">=</span> <span class="n">declarative_base</span><span class="p">()</span>
793
<span class="n">DBSession</span> <span class="o">=</span> <span class="n">scoped_session</span><span class="p">(</span><span class="n">sessionmaker</span><span class="p">())</span>
794
<span class="n">engine</span> <span class="o">=</span> <span class="bp">None</span>
796
<span class="k">class</span> <span class="nc">Customer</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
797
<span class="n">__tablename__</span> <span class="o">=</span> <span class="s">"customer"</span>
798
<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>
799
<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><span class="mi">255</span><span class="p">))</span>
801
<span class="k">def</span> <span class="nf">init_sqlalchemy</span><span class="p">(</span><span class="n">dbname</span><span class="o">=</span><span class="s">'sqlite:///sqlalchemy.db'</span><span class="p">):</span>
802
<span class="k">global</span> <span class="n">engine</span>
803
<span class="n">engine</span> <span class="o">=</span> <span class="n">create_engine</span><span class="p">(</span><span class="n">dbname</span><span class="p">,</span> <span class="n">echo</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
804
<span class="n">DBSession</span><span class="o">.</span><span class="n">remove</span><span class="p">()</span>
805
<span class="n">DBSession</span><span class="o">.</span><span class="n">configure</span><span class="p">(</span><span class="n">bind</span><span class="o">=</span><span class="n">engine</span><span class="p">,</span> <span class="n">autoflush</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">expire_on_commit</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
806
<span class="n">Base</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">drop_all</span><span class="p">(</span><span class="n">engine</span><span class="p">)</span>
807
<span class="n">Base</span><span class="o">.</span><span class="n">metadata</span><span class="o">.</span><span class="n">create_all</span><span class="p">(</span><span class="n">engine</span><span class="p">)</span>
809
<span class="k">def</span> <span class="nf">test_sqlalchemy_orm</span><span class="p">(</span><span class="n">n</span><span class="o">=</span><span class="mi">100000</span><span class="p">):</span>
810
<span class="n">init_sqlalchemy</span><span class="p">()</span>
811
<span class="n">t0</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
812
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
813
<span class="n">customer</span> <span class="o">=</span> <span class="n">Customer</span><span class="p">()</span>
814
<span class="n">customer</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="s">'NAME '</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
815
<span class="n">DBSession</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">customer</span><span class="p">)</span>
816
<span class="k">if</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">1000</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
817
<span class="n">DBSession</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
818
<span class="n">DBSession</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
819
<span class="k">print</span><span class="p">(</span><span class="s">"SQLAlchemy ORM: Total time for "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="o">+</span>
820
<span class="s">" records "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">t0</span><span class="p">)</span> <span class="o">+</span> <span class="s">" secs"</span><span class="p">)</span>
822
<span class="k">def</span> <span class="nf">test_sqlalchemy_orm_pk_given</span><span class="p">(</span><span class="n">n</span><span class="o">=</span><span class="mi">100000</span><span class="p">):</span>
823
<span class="n">init_sqlalchemy</span><span class="p">()</span>
824
<span class="n">t0</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
825
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
826
<span class="n">customer</span> <span class="o">=</span> <span class="n">Customer</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">"NAME "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">))</span>
827
<span class="n">DBSession</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">customer</span><span class="p">)</span>
828
<span class="k">if</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">1000</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
829
<span class="n">DBSession</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
830
<span class="n">DBSession</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
831
<span class="k">print</span><span class="p">(</span><span class="s">"SQLAlchemy ORM pk given: Total time for "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="o">+</span>
832
<span class="s">" records "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">t0</span><span class="p">)</span> <span class="o">+</span> <span class="s">" secs"</span><span class="p">)</span>
834
<span class="k">def</span> <span class="nf">test_sqlalchemy_core</span><span class="p">(</span><span class="n">n</span><span class="o">=</span><span class="mi">100000</span><span class="p">):</span>
835
<span class="n">init_sqlalchemy</span><span class="p">()</span>
836
<span class="n">t0</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
837
<span class="n">engine</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
838
<span class="n">Customer</span><span class="o">.</span><span class="n">__table__</span><span class="o">.</span><span class="n">insert</span><span class="p">(),</span>
839
<span class="p">[{</span><span class="s">"name"</span><span class="p">:</span> <span class="s">'NAME '</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">)}</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">)]</span>
840
<span class="p">)</span>
841
<span class="k">print</span><span class="p">(</span><span class="s">"SQLAlchemy Core: Total time for "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="o">+</span>
842
<span class="s">" records "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">t0</span><span class="p">)</span> <span class="o">+</span> <span class="s">" secs"</span><span class="p">)</span>
844
<span class="k">def</span> <span class="nf">init_sqlite3</span><span class="p">(</span><span class="n">dbname</span><span class="p">):</span>
845
<span class="n">conn</span> <span class="o">=</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">dbname</span><span class="p">)</span>
846
<span class="n">c</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
847
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s">"DROP TABLE IF EXISTS customer"</span><span class="p">)</span>
848
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s">"CREATE TABLE customer (id INTEGER NOT NULL, "</span>
849
<span class="s">"name VARCHAR(255), PRIMARY KEY(id))"</span><span class="p">)</span>
850
<span class="n">conn</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
851
<span class="k">return</span> <span class="n">conn</span>
853
<span class="k">def</span> <span class="nf">test_sqlite3</span><span class="p">(</span><span class="n">n</span><span class="o">=</span><span class="mi">100000</span><span class="p">,</span> <span class="n">dbname</span><span class="o">=</span><span class="s">'sqlite3.db'</span><span class="p">):</span>
854
<span class="n">conn</span> <span class="o">=</span> <span class="n">init_sqlite3</span><span class="p">(</span><span class="n">dbname</span><span class="p">)</span>
855
<span class="n">c</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span>
856
<span class="n">t0</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
857
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
858
<span class="n">row</span> <span class="o">=</span> <span class="p">(</span><span class="s">'NAME '</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">),)</span>
859
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s">"INSERT INTO customer (name) VALUES (?)"</span><span class="p">,</span> <span class="n">row</span><span class="p">)</span>
860
<span class="n">conn</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
861
<span class="k">print</span><span class="p">(</span><span class="s">"sqlite3: Total time for "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="o">+</span>
862
<span class="s">" records "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">t0</span><span class="p">)</span> <span class="o">+</span> <span class="s">" sec"</span><span class="p">)</span>
864
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
865
<span class="n">test_sqlalchemy_orm</span><span class="p">(</span><span class="mi">100000</span><span class="p">)</span>
866
<span class="n">test_sqlalchemy_orm_pk_given</span><span class="p">(</span><span class="mi">100000</span><span class="p">)</span>
867
<span class="n">test_sqlalchemy_core</span><span class="p">(</span><span class="mi">100000</span><span class="p">)</span>
868
<span class="n">test_sqlite3</span><span class="p">(</span><span class="mi">100000</span><span class="p">)</span></pre></div>
871
<div class="section" id="how-do-i-make-a-query-that-always-adds-a-certain-filter-to-every-query">
872
<h3>How do I make a Query that always adds a certain filter to every query?<a class="headerlink" href="#how-do-i-make-a-query-that-always-adds-a-certain-filter-to-every-query" title="Permalink to this headline">¶</a></h3>
873
<p>See the recipe at <a class="reference external" href="http://www.sqlalchemy.org/trac/wiki/UsageRecipes/PreFilteredQuery">PreFilteredQuery</a>.</p>
875
<div class="section" id="i-ve-created-a-mapping-against-an-outer-join-and-while-the-query-returns-rows-no-objects-are-returned-why-not">
876
<h3>I’ve created a mapping against an Outer Join, and while the query returns rows, no objects are returned. Why not?<a class="headerlink" href="#i-ve-created-a-mapping-against-an-outer-join-and-while-the-query-returns-rows-no-objects-are-returned-why-not" title="Permalink to this headline">¶</a></h3>
877
<p>Rows returned by an outer join may contain NULL for part of the primary key,
878
as the primary key is the composite of both tables. The <a class="reference internal" href="orm/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 ignores incoming rows
879
that don’t have an acceptable primary key. Based on the setting of the <tt class="docutils literal"><span class="pre">allow_partial_pks</span></tt>
880
flag on <a class="reference internal" href="orm/mapper_config.html#sqlalchemy.orm.mapper" title="sqlalchemy.orm.mapper"><tt class="xref py py-func docutils literal"><span class="pre">mapper()</span></tt></a>, a primary key is accepted if the value has at least one non-NULL
881
value, or alternatively if the value has no NULL values. See <tt class="docutils literal"><span class="pre">allow_partial_pks</span></tt>
882
at <a class="reference internal" href="orm/mapper_config.html#sqlalchemy.orm.mapper" title="sqlalchemy.orm.mapper"><tt class="xref py py-func docutils literal"><span class="pre">mapper()</span></tt></a>.</p>
884
<div class="section" id="i-m-using-joinedload-or-lazy-false-to-create-a-join-outer-join-and-sqlalchemy-is-not-constructing-the-correct-query-when-i-try-to-add-a-where-order-by-limit-etc-which-relies-upon-the-outer-join">
885
<h3>I’m using <tt class="docutils literal"><span class="pre">joinedload()</span></tt> or <tt class="docutils literal"><span class="pre">lazy=False</span></tt> to create a JOIN/OUTER JOIN and SQLAlchemy is not constructing the correct query when I try to add a WHERE, ORDER BY, LIMIT, etc. (which relies upon the (OUTER) JOIN)<a class="headerlink" href="#i-m-using-joinedload-or-lazy-false-to-create-a-join-outer-join-and-sqlalchemy-is-not-constructing-the-correct-query-when-i-try-to-add-a-where-order-by-limit-etc-which-relies-upon-the-outer-join" title="Permalink to this headline">¶</a></h3>
886
<p>The joins generated by joined eager loading are only used to fully load related
887
collections, and are designed to have no impact on the primary results of the query.
888
Since they are anonymously aliased, they cannot be referenced directly.</p>
889
<p>For detail on this beahvior, see <a class="reference internal" href="orm/loading.html"><em>Relationship Loading Techniques</em></a>.</p>
891
<div class="section" id="query-has-no-len-why-not">
892
<h3>Query has no <tt class="docutils literal"><span class="pre">__len__()</span></tt>, why not?<a class="headerlink" href="#query-has-no-len-why-not" title="Permalink to this headline">¶</a></h3>
893
<p>The Python <tt class="docutils literal"><span class="pre">__len__()</span></tt> magic method applied to an object allows the <tt class="docutils literal"><span class="pre">len()</span></tt>
894
builtin to be used to determine the length of the collection. It’s intuitive
895
that a SQL query object would link <tt class="docutils literal"><span class="pre">__len__()</span></tt> to the <a class="reference internal" href="orm/query.html#sqlalchemy.orm.query.Query.count" title="sqlalchemy.orm.query.Query.count"><tt class="xref py py-meth docutils literal"><span class="pre">Query.count()</span></tt></a>
896
method, which emits a <cite>SELECT COUNT</cite>. The reason this is not possible is
897
because evaluating the query as a list would incur two SQL calls instead of
899
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Iterates</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
900
<span class="k">def</span> <span class="nf">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
901
<span class="k">print</span> <span class="s">"LEN!"</span>
902
<span class="k">return</span> <span class="mi">5</span>
904
<span class="k">def</span> <span class="nf">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
905
<span class="k">print</span> <span class="s">"ITER!"</span>
906
<span class="k">return</span> <span class="nb">iter</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">])</span>
908
<span class="nb">list</span><span class="p">(</span><span class="n">Iterates</span><span class="p">())</span></pre></div>
911
<div class="highlight-python"><pre>ITER!
915
<div class="section" id="how-do-i-use-textual-sql-with-orm-queries">
916
<h3>How Do I use Textual SQL with ORM Queries?<a class="headerlink" href="#how-do-i-use-textual-sql-with-orm-queries" title="Permalink to this headline">¶</a></h3>
919
<li><a class="reference internal" href="orm/tutorial.html#orm-tutorial-literal-sql"><em>Using Literal SQL</em></a> - Ad-hoc textual blocks with <a class="reference internal" href="orm/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></li>
920
<li><a class="reference internal" href="orm/session.html#session-sql-expressions"><em>Using SQL Expressions with Sessions</em></a> - Using <a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session" title="sqlalchemy.orm.session.Session"><tt class="xref py py-class docutils literal"><span class="pre">Session</span></tt></a> with textual SQL directly.</li>
923
<div class="section" id="i-m-calling-session-delete-myobject-and-it-isn-t-removed-from-the-parent-collection">
924
<h3>I’m calling <tt class="docutils literal"><span class="pre">Session.delete(myobject)</span></tt> and it isn’t removed from the parent collection!<a class="headerlink" href="#i-m-calling-session-delete-myobject-and-it-isn-t-removed-from-the-parent-collection" title="Permalink to this headline">¶</a></h3>
925
<p>See <a class="reference internal" href="orm/session.html#session-deleting-from-collections"><em>Deleting from Collections</em></a> for a description of this behavior.</p>
927
<div class="section" id="why-isnt-my-init-called-when-i-load-objects">
928
<h3>why isnt my <tt class="docutils literal"><span class="pre">__init__()</span></tt> called when I load objects?<a class="headerlink" href="#why-isnt-my-init-called-when-i-load-objects" title="Permalink to this headline">¶</a></h3>
929
<p>See <a class="reference internal" href="orm/mapper_config.html#mapping-constructors"><em>Constructors and Object Initialization</em></a> for a description of this behavior.</p>
931
<div class="section" id="how-do-i-use-on-delete-cascade-with-sa-s-orm">
932
<h3>how do I use ON DELETE CASCADE with SA’s ORM?<a class="headerlink" href="#how-do-i-use-on-delete-cascade-with-sa-s-orm" title="Permalink to this headline">¶</a></h3>
933
<p>SQLAlchemy will always issue UPDATE or DELETE statements for dependent
934
rows which are currently loaded in the <a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session" title="sqlalchemy.orm.session.Session"><tt class="xref py py-class docutils literal"><span class="pre">Session</span></tt></a>. For rows which
935
are not loaded, it will by default issue SELECT statements to load
936
those rows and udpate/delete those as well; in other words it assumes
937
there is no ON DELETE CASCADE configured.
938
To configure SQLAlchemy to cooperate with ON DELETE CASCADE, see
939
<a class="reference internal" href="orm/collections.html#passive-deletes"><em>Using Passive Deletes</em></a>.</p>
941
<div class="section" id="i-set-the-foo-id-attribute-on-my-instance-to-7-but-the-foo-attribute-is-still-none-shouldn-t-it-have-loaded-foo-with-id-7">
942
<h3>I set the “foo_id” attribute on my instance to “7”, but the “foo” attribute is still <tt class="docutils literal"><span class="pre">None</span></tt> - shouldn’t it have loaded Foo with id #7?<a class="headerlink" href="#i-set-the-foo-id-attribute-on-my-instance-to-7-but-the-foo-attribute-is-still-none-shouldn-t-it-have-loaded-foo-with-id-7" title="Permalink to this headline">¶</a></h3>
943
<p>The ORM is not constructed in such a way as to support
944
immediate population of relationships driven from foreign
945
key attribute changes - instead, it is designed to work the
946
other way around - foreign key attributes are handled by the
947
ORM behind the scenes, the end user sets up object
948
relationships naturally. Therefore, the recommended way to
949
set <tt class="docutils literal"><span class="pre">o.foo</span></tt> is to do just that - set it!:</p>
950
<div class="highlight-python"><div class="highlight"><pre><span class="n">foo</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">Foo</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>
951
<span class="n">o</span><span class="o">.</span><span class="n">foo</span> <span class="o">=</span> <span class="n">foo</span>
952
<span class="n">Session</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span></pre></div>
954
<p>Manipulation of foreign key attributes is of course entirely legal. However,
955
setting a foreign-key attribute to a new value currently does not trigger
956
an “expire” event of the <a class="reference internal" href="orm/relationships.html#sqlalchemy.orm.relationship" title="sqlalchemy.orm.relationship"><tt class="xref py py-func docutils literal"><span class="pre">relationship()</span></tt></a> in which it’s involved (this may
957
be implemented in the future). This means
958
that for the following sequence:</p>
959
<div class="highlight-python"><div class="highlight"><pre><span class="n">o</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">SomeClass</span><span class="p">)</span><span class="o">.</span><span class="n">first</span><span class="p">()</span>
960
<span class="k">assert</span> <span class="n">o</span><span class="o">.</span><span class="n">foo</span> <span class="ow">is</span> <span class="bp">None</span>
961
<span class="n">o</span><span class="o">.</span><span class="n">foo_id</span> <span class="o">=</span> <span class="mi">7</span></pre></div>
963
<p><tt class="docutils literal"><span class="pre">o.foo</span></tt> is loaded when we checked it for <tt class="docutils literal"><span class="pre">None</span></tt>. Setting
964
<tt class="docutils literal"><span class="pre">o.foo_id=7</span></tt> will have the value of “7” as pending, but no flush
966
<p>For <tt class="docutils literal"><span class="pre">o.foo</span></tt> to load based on the foreign key mutation is usually achieved
967
naturally after the commit, which both flushes the new foreign key value
968
and expires all state:</p>
969
<div class="highlight-python"><pre>Session.commit()
970
assert o.foo is <Foo object with id 7></pre>
972
<p>A more minimal operation is to expire the attribute individually. The
973
<a class="reference internal" href="orm/session.html#sqlalchemy.orm.session.Session.flush" title="sqlalchemy.orm.session.Session.flush"><tt class="xref py py-meth docutils literal"><span class="pre">Session.flush()</span></tt></a> is also needed if the object is pending (hasn’t been INSERTed yet),
974
or if the relationship is many-to-one prior to 0.6.5:</p>
975
<div class="highlight-python"><pre>Session.expire(o, ['foo'])
979
assert o.foo is <Foo object with id 7></pre>
981
<p>Where above, expiring the attribute triggers a lazy load on the next access of <tt class="docutils literal"><span class="pre">o.foo</span></tt>.</p>
982
<p>The object does not “autoflush” on access of <tt class="docutils literal"><span class="pre">o.foo</span></tt> if the object is pending, since
983
it is usually desirable that a pending object doesn’t autoflush prematurely and/or
984
excessively, while its state is still being populated.</p>
985
<p>Also see the recipe <a class="reference external" href="http://www.sqlalchemy.org/trac/wiki/UsageRecipes/ExpireRelationshipOnFKChange">ExpireRelationshipOnFKChange</a>, which features a mechanism to actually achieve this behavior to a reasonable degree in simple situations.</p>
987
<div class="section" id="is-there-a-way-to-automagically-have-only-unique-keywords-or-other-kinds-of-objects-without-doing-a-query-for-the-keyword-and-getting-a-reference-to-the-row-containing-that-keyword">
988
<h3>Is there a way to automagically have only unique keywords (or other kinds of objects) without doing a query for the keyword and getting a reference to the row containing that keyword?<a class="headerlink" href="#is-there-a-way-to-automagically-have-only-unique-keywords-or-other-kinds-of-objects-without-doing-a-query-for-the-keyword-and-getting-a-reference-to-the-row-containing-that-keyword" title="Permalink to this headline">¶</a></h3>
989
<p>When people read the many-to-many example in the docs, they get hit with the
990
fact that if you create the same <tt class="docutils literal"><span class="pre">Keyword</span></tt> twice, it gets put in the DB twice.
991
Which is somewhat inconvenient.</p>
992
<p>This <a class="reference external" href="http://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject">UniqueObject</a> recipe was created to address this issue.</p>
1001
<div id="docs-bottom-navigation" class="docs-navigation-links">
1003
<div id="docs-copyright">
1004
© <a href="copyright.html">Copyright</a> 2007-2013, the SQLAlchemy authors and contributors.
1005
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.2b1.