~ubuntu-branches/debian/sid/sqlalchemy/sid

« back to all changes in this revision

Viewing changes to doc/build/faq.rst

  • Committer: Package Import Robot
  • Author(s): Piotr Ożarowski
  • Date: 2014-06-27 20:17:13 UTC
  • mfrom: (1.4.28)
  • Revision ID: package-import@ubuntu.com-20140627201713-g6p1kq8q1qenztrv
Tags: 0.9.6-1
* New upstream release
* Remove Python 3.X build tag files, thanks to Matthias Urlichs for the
  patch (closes: #747852)
* python-fdb isn't in the Debian archive yet so default dialect for firebird://
  URLs is changed to obsolete kinterbasdb, thanks to Russell Stuart for the
  patch (closes: #752145)

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
============================
8
8
 
9
9
.. contents::
10
 
        :local:
11
 
        :class: faq
12
 
        :backlinks: none
 
10
    :local:
 
11
    :class: faq
 
12
    :backlinks: none
13
13
 
14
14
 
15
15
Connections / Engines
35
35
The :func:`.create_engine` call accepts additional arguments either
36
36
directly via the ``connect_args`` keyword argument::
37
37
 
38
 
        e = create_engine("mysql://scott:tiger@localhost/test",
39
 
                                                connect_args={"encoding": "utf8"})
 
38
    e = create_engine("mysql://scott:tiger@localhost/test",
 
39
                        connect_args={"encoding": "utf8"})
40
40
 
41
41
Or for basic string and integer arguments, they can usually be specified
42
42
in the query string of the URL::
43
43
 
44
 
        e = create_engine("mysql://scott:tiger@localhost/test?encoding=utf8")
 
44
    e = create_engine("mysql://scott:tiger@localhost/test?encoding=utf8")
45
45
 
46
46
.. seealso::
47
47
 
48
 
        :ref:`custom_dbapi_args`
 
48
    :ref:`custom_dbapi_args`
49
49
 
50
50
"MySQL Server has gone away"
51
51
----------------------------
87
87
The behavior of the connection pool's connection return behavior can be
88
88
configured using ``reset_on_return``::
89
89
 
90
 
        from sqlalchemy import create_engine
91
 
        from sqlalchemy.pool import QueuePool
 
90
    from sqlalchemy import create_engine
 
91
    from sqlalchemy.pool import QueuePool
92
92
 
93
 
        engine = create_engine('mysql://scott:tiger@localhost/myisam_database', pool=QueuePool(reset_on_return=False))
 
93
    engine = create_engine('mysql://scott:tiger@localhost/myisam_database', pool=QueuePool(reset_on_return=False))
94
94
 
95
95
I'm on SQL Server - how do I turn those ROLLBACKs into COMMITs?
96
96
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
99
99
to ``True``, ``False``, and ``None``.   Setting to ``commit`` will cause
100
100
a COMMIT as any connection is returned to the pool::
101
101
 
102
 
        engine = create_engine('mssql://scott:tiger@mydsn', pool=QueuePool(reset_on_return='commit'))
 
102
    engine = create_engine('mssql://scott:tiger@mydsn', pool=QueuePool(reset_on_return='commit'))
103
103
 
104
104
 
105
105
I am using multiple connections with a SQLite database (typically to test transaction operation), and my test program is not working!
115
115
 
116
116
.. seealso::
117
117
 
118
 
        :ref:`pysqlite_threading_pooling` - info on PySQLite's behavior.
 
118
    :ref:`pysqlite_threading_pooling` - info on PySQLite's behavior.
119
119
 
120
120
How do I get at the raw DBAPI connection when using an Engine?
121
121
--------------------------------------------------------------
126
126
:attr:`.ConnectionFairy.connection` attribute on that - but there should never be any need to access
127
127
the non-pool-proxied DBAPI connection, as all methods are proxied through::
128
128
 
129
 
        engine = create_engine(...)
130
 
        conn = engine.connect()
131
 
        conn.connection.<do DBAPI things>
132
 
        cursor = conn.connection.cursor(<DBAPI specific arguments..>)
 
129
    engine = create_engine(...)
 
130
    conn = engine.connect()
 
131
    conn.connection.<do DBAPI things>
 
132
    cursor = conn.connection.cursor(<DBAPI specific arguments..>)
133
133
 
134
134
You must ensure that you revert any isolation level settings or other
135
135
operation-specific settings on the connection back to normal before returning
140
140
the connection from the pool such that it will be closed and discarded
141
141
when :meth:`.Connection.close` is called::
142
142
 
143
 
        conn = engine.connect()
144
 
        conn.detach()  # detaches the DBAPI connection from the connection pool
145
 
        conn.connection.<go nuts>
146
 
        conn.close()  # connection is closed for real, the pool replaces it with a new connection
 
143
    conn = engine.connect()
 
144
    conn.detach()  # detaches the DBAPI connection from the connection pool
 
145
    conn.connection.<go nuts>
 
146
    conn.close()  # connection is closed for real, the pool replaces it with a new connection
147
147
 
148
148
MetaData / Schema
149
149
==================
156
156
contains locks on the table and is distinct from the connection being used for
157
157
the DROP statement.  Heres the most minimal version of the pattern::
158
158
 
159
 
        connection = engine.connect()
160
 
        result = connection.execute(mytable.select())
 
159
    connection = engine.connect()
 
160
    result = connection.execute(mytable.select())
161
161
 
162
 
        mytable.drop(engine)
 
162
    mytable.drop(engine)
163
163
 
164
164
Above, a connection pool connection is still checked out; furthermore, the
165
165
result object above also maintains a link to this connection.  If
171
171
 
172
172
The solution is to close out all connections before emitting DROP TABLE::
173
173
 
174
 
        connection = engine.connect()
175
 
        result = connection.execute(mytable.select())
176
 
 
177
 
        # fully read result sets
178
 
        result.fetchall()
179
 
 
180
 
        # close connections
181
 
        connection.close()
182
 
 
183
 
        # now locks are removed
184
 
        mytable.drop(engine)
 
174
    connection = engine.connect()
 
175
    result = connection.execute(mytable.select())
 
176
 
 
177
    # fully read result sets
 
178
    result.fetchall()
 
179
 
 
180
    # close connections
 
181
    connection.close()
 
182
 
 
183
    # now locks are removed
 
184
    mytable.drop(engine)
185
185
 
186
186
Does SQLAlchemy support ALTER TABLE, CREATE VIEW, CREATE TRIGGER, Schema Upgrade Functionality?
187
187
-----------------------------------------------------------------------------------------------
198
198
 
199
199
This is available via the :attr:`.MetaData.sorted_tables` function::
200
200
 
201
 
        metadata = MetaData()
202
 
        # ... add Table objects to metadata
203
 
        ti = metadata.sorted_tables:
204
 
        for t in ti:
205
 
            print t
 
201
    metadata = MetaData()
 
202
    # ... add Table objects to metadata
 
203
    ti = metadata.sorted_tables:
 
204
    for t in ti:
 
205
        print t
206
206
 
207
207
How can I get the CREATE TABLE/ DROP TABLE output as a string?
208
208
---------------------------------------------------------------
210
210
Modern SQLAlchemy has clause constructs which represent DDL operations. These
211
211
can be rendered to strings like any other SQL expression::
212
212
 
213
 
        from sqlalchemy.schema import CreateTable
 
213
    from sqlalchemy.schema import CreateTable
214
214
 
215
 
        print CreateTable(mytable)
 
215
    print CreateTable(mytable)
216
216
 
217
217
To get the string specific to a certain engine::
218
218
 
219
 
        print CreateTable(mytable).compile(engine)
 
219
    print CreateTable(mytable).compile(engine)
220
220
 
221
221
There's also a special form of :class:`.Engine` that can let you dump an entire
222
222
metadata creation sequence, using this recipe::
223
223
 
224
 
        def dump(sql, *multiparams, **params):
225
 
            print sql.compile(dialect=engine.dialect)
226
 
        engine = create_engine('postgresql://', strategy='mock', executor=dump)
227
 
        metadata.create_all(engine, checkfirst=False)
 
224
    def dump(sql, *multiparams, **params):
 
225
        print sql.compile(dialect=engine.dialect)
 
226
    engine = create_engine('postgresql://', strategy='mock', executor=dump)
 
227
    metadata.create_all(engine, checkfirst=False)
228
228
 
229
229
The `Alembic <https://bitbucket.org/zzzeek/alembic>`_ tool also supports
230
230
an "offline" SQL generation mode that renders database migrations as SQL scripts.
243
243
SQL Expressions
244
244
=================
245
245
 
 
246
.. _faq_sql_expression_string:
 
247
 
 
248
How do I render SQL expressions as strings, possibly with bound parameters inlined?
 
249
------------------------------------------------------------------------------------
 
250
 
 
251
The "stringification" of a SQLAlchemy statement or Query in the vast majority
 
252
of cases is as simple as::
 
253
 
 
254
    print str(statement)
 
255
 
 
256
this applies both to an ORM :class:`~.orm.query.Query` as well as any :func:`.select` or other
 
257
statement.   Additionally, to get the statement as compiled to a
 
258
specific dialect or engine, if the statement itself is not already
 
259
bound to one you can pass this in to :meth:`.ClauseElement.compile`::
 
260
 
 
261
    print statement.compile(someengine)
 
262
 
 
263
or without an :class:`.Engine`::
 
264
 
 
265
    from sqlalchemy.dialects import postgresql
 
266
    print statement.compile(dialect=postgresql.dialect())
 
267
 
 
268
When given an ORM :class:`~.orm.query.Query` object, in order to get at the
 
269
:meth:`.ClauseElement.compile`
 
270
method we only need access the :attr:`~.orm.query.Query.statement`
 
271
accessor first::
 
272
 
 
273
    statement = query.statement
 
274
    print statement.compile(someengine)
 
275
 
 
276
The above forms will render the SQL statement as it is passed to the Python
 
277
:term:`DBAPI`, which includes that bound parameters are not rendered inline.
 
278
SQLAlchemy normally does not stringify bound parameters, as this is handled
 
279
appropriately by the Python DBAPI, not to mention bypassing bound
 
280
parameters is probably the most widely exploited security hole in
 
281
modern web applications.   SQLAlchemy has limited ability to do this
 
282
stringification in certain circumstances such as that of emitting DDL.
 
283
In order to access this functionality one can use the ``literal_binds``
 
284
flag, passed to ``compile_kwargs``::
 
285
 
 
286
    from sqlalchemy.sql import table, column, select
 
287
 
 
288
    t = table('t', column('x'))
 
289
 
 
290
    s = select([t]).where(t.c.x == 5)
 
291
 
 
292
    print s.compile(compile_kwargs={"literal_binds": True})
 
293
 
 
294
the above approach has the caveats that it is only supported for basic
 
295
types, such as ints and strings, and furthermore if a :func:`.bindparam`
 
296
without a pre-set value is used directly, it won't be able to
 
297
stringify that either.    Additionally, the ``compile_kwargs`` argument
 
298
itself is only available as of SQLAlchemy 0.9; and there are slightly
 
299
more verbose ways of getting ``literal_binds`` injected with 0.8.
 
300
 
 
301
.. topic::  Applying compiler kw arguments prior to 0.9
 
302
 
 
303
    We can provide a fixed set of ``**kw`` by calling upon ``process()``
 
304
    directly::
 
305
 
 
306
        compiled = s.compile()
 
307
        print compiled.process(s, literal_binds=True)
 
308
 
 
309
    Note that in this approach the statement is actually being stringified
 
310
    twice, hence using ``compile_kwargs`` in 0.9 should be preferred.
 
311
 
 
312
 
 
313
If we want to skip using ``literal_binds`` altogether due to the above
 
314
caveats, we can take the approach of replacing them out ahead of time
 
315
with whatever we want::
 
316
 
 
317
    from sqlalchemy.sql import visitors, text
 
318
 
 
319
    def replace_bindparam(element):
 
320
        if hasattr(element, 'effective_value'):
 
321
            return text(str(element.effective_value))
 
322
 
 
323
    s = visitors.replacement_traverse(s, {}, replace_bindparam)
 
324
    print s
 
325
 
 
326
Still another approach to injecting functionality where bound
 
327
parameters are concerned is to use the :doc:`Compilation Extension
 
328
API <core/compiler>`::
 
329
 
 
330
    from sqlalchemy.ext.compiler import compiles
 
331
    from sqlalchemy.sql.expression import BindParameter
 
332
 
 
333
    s = select([t]).where(t.c.x == 5)
 
334
 
 
335
    @compiles(BindParameter)
 
336
    def as_str(element, compiler, **kw):
 
337
        if 'binds_as_str' in kw:
 
338
            return str(element.effective_value)
 
339
        else:
 
340
            return compiler.visit_bindparam(element, **kw)
 
341
 
 
342
    print s.compile(compile_kwargs={"binds_as_str": True})
 
343
 
 
344
Above, we pass a self-defined flag ``binds_as_str`` through the compiler,
 
345
which we then intercept within our custom render method for :class:`.BindParameter`.
 
346
 
246
347
Why does ``.col.in_([])`` Produce ``col != col``? Why not ``1=0``?
247
348
-------------------------------------------------------------------
248
349
 
250
351
elements to compare against a column, generally does not accept an empty list,
251
352
that is while it is valid to say::
252
353
 
253
 
        column IN (1, 2, 3)
 
354
    column IN (1, 2, 3)
254
355
 
255
356
it's not valid to say::
256
357
 
257
 
        column IN ()
 
358
    column IN ()
258
359
 
259
360
SQLAlchemy's :meth:`.Operators.in_` operator, when given an empty list, produces this
260
361
expression::
261
362
 
262
 
        column != column
 
363
    column != column
263
364
 
264
365
As of version 0.6, it also produces a warning stating that a less efficient
265
366
comparison operation will be rendered. This expression is the only one that is
268
369
For example, the naive approach of "just evaluate to false, by comparing 1=0
269
370
or 1!=1", does not handle nulls properly. An expression like::
270
371
 
271
 
        NOT column != column
 
372
    NOT column != column
272
373
 
273
374
will not return a row when "column" is null, but an expression which does not
274
375
take the column into account::
275
376
 
276
 
        NOT 1=0
 
377
    NOT 1=0
277
378
 
278
379
will.
279
380
 
280
381
Closer to the mark is the following CASE expression::
281
382
 
282
 
        CASE WHEN column IS NOT NULL THEN 1=0 ELSE NULL END
 
383
    CASE WHEN column IS NOT NULL THEN 1=0 ELSE NULL END
283
384
 
284
385
We don't use this expression due to its verbosity, and its also not
285
386
typically accepted by Oracle within a WHERE clause - depending
323
424
 
324
425
.. note::
325
426
 
326
 
        It's important to note that we're only talking about the SQLAlchemy ORM; an
327
 
        application which builds on Core and deals only with :class:`.Table` objects,
328
 
        :func:`.select` constructs and the like, **does not** need any primary key
329
 
        to be present on or associated with a table in any way (though again, in SQL, all tables
330
 
        should really have some kind of primary key, lest you need to actually
331
 
        update or delete specific rows).
 
427
    It's important to note that we're only talking about the SQLAlchemy ORM; an
 
428
    application which builds on Core and deals only with :class:`.Table` objects,
 
429
    :func:`.select` constructs and the like, **does not** need any primary key
 
430
    to be present on or associated with a table in any way (though again, in SQL, all tables
 
431
    should really have some kind of primary key, lest you need to actually
 
432
    update or delete specific rows).
332
433
 
333
434
In almost all cases, a table does have a so-called :term:`candidate key`, which is a column or series
334
435
of columns that uniquely identify a row.  If a table truly doesn't have this, and has actual
335
436
fully duplicate rows, the table is not corresponding to `first normal form <http://en.wikipedia.org/wiki/First_normal_form>`_ and cannot be mapped.   Otherwise, whatever columns comprise the best candidate key can be
336
437
applied directly to the mapper::
337
438
 
338
 
        class SomeClass(Base):
339
 
                __table__ = some_table_with_no_pk
340
 
                __mapper_args__ = {
341
 
                        'primary_key':[some_table_with_no_pk.c.uid, some_table_with_no_pk.c.bar]
342
 
                }
 
439
    class SomeClass(Base):
 
440
        __table__ = some_table_with_no_pk
 
441
        __mapper_args__ = {
 
442
            'primary_key':[some_table_with_no_pk.c.uid, some_table_with_no_pk.c.bar]
 
443
        }
343
444
 
344
445
Better yet is when using fully declared table metadata, use the ``primary_key=True``
345
446
flag on those columns::
346
447
 
347
 
        class SomeClass(Base):
348
 
                __tablename__ = "some_table_with_no_pk"
 
448
    class SomeClass(Base):
 
449
        __tablename__ = "some_table_with_no_pk"
349
450
 
350
 
                uid = Column(Integer, primary_key=True)
351
 
                bar = Column(String, primary_key=True)
 
451
        uid = Column(Integer, primary_key=True)
 
452
        bar = Column(String, primary_key=True)
352
453
 
353
454
All tables in a relational database should have primary keys.   Even a many-to-many
354
455
association table - the primary key would be the composite of the two association
355
456
columns::
356
457
 
357
 
        CREATE TABLE my_association (
358
 
          user_id INTEGER REFERENCES user(id),
359
 
          account_id INTEGER REFERENCES account(id),
360
 
          PRIMARY KEY (user_id, account_id)
361
 
        )
 
458
    CREATE TABLE my_association (
 
459
      user_id INTEGER REFERENCES user(id),
 
460
      account_id INTEGER REFERENCES account(id),
 
461
      PRIMARY KEY (user_id, account_id)
 
462
    )
362
463
 
363
464
 
364
465
How do I configure a Column that is a Python reserved word or similar?
375
476
To get at the :class:`.Mapper` for a particular mapped class, call the
376
477
:func:`.inspect` function on it::
377
478
 
378
 
        from sqlalchemy import inspect
 
479
    from sqlalchemy import inspect
379
480
 
380
 
        mapper = inspect(MyClass)
 
481
    mapper = inspect(MyClass)
381
482
 
382
483
From there, all information about the class can be acquired using such methods as:
383
484
 
404
505
  this differs from :attr:`.Mapper.mapped_table` in the case of a mapper mapped
405
506
  using inheritance to a composed selectable.
406
507
 
 
508
.. _faq_combining_columns:
 
509
 
 
510
I'm getting a warning or error about "Implicitly combining column X under attribute Y"
 
511
--------------------------------------------------------------------------------------
 
512
 
 
513
This condition refers to when a mapping contains two columns that are being
 
514
mapped under the same attribute name due to their name, but there's no indication
 
515
that this is intentional.  A mapped class needs to have explicit names for
 
516
every attribute that is to store an independent value; when two columns have the
 
517
same name and aren't disambiguated, they fall under the same attribute and
 
518
the effect is that the value from one column is **copied** into the other, based
 
519
on which column was assigned to the attribute first.
 
520
 
 
521
This behavior is often desirable and is allowed without warning in the case
 
522
where the two columns are linked together via a foreign key relationship
 
523
within an inheritance mapping.   When the warning or exception occurs, the
 
524
issue can be resolved by either assigning the columns to differently-named
 
525
attributes, or if combining them together is desired, by using
 
526
:func:`.column_property` to make this explicit.
 
527
 
 
528
Given the example as follows::
 
529
 
 
530
    from sqlalchemy import Integer, Column, ForeignKey
 
531
    from sqlalchemy.ext.declarative import declarative_base
 
532
 
 
533
    Base = declarative_base()
 
534
 
 
535
    class A(Base):
 
536
        __tablename__ = 'a'
 
537
 
 
538
        id = Column(Integer, primary_key=True)
 
539
 
 
540
    class B(A):
 
541
        __tablename__ = 'b'
 
542
 
 
543
        id = Column(Integer, primary_key=True)
 
544
        a_id = Column(Integer, ForeignKey('a.id'))
 
545
 
 
546
As of SQLAlchemy version 0.9.5, the above condition is detected, and will
 
547
warn that the ``id`` column of ``A`` and ``B`` is being combined under
 
548
the same-named attribute ``id``, which above is a serious issue since it means
 
549
that a ``B`` object's primary key will always mirror that of its ``A``.
 
550
 
 
551
A mapping which resolves this is as follows::
 
552
 
 
553
    class A(Base):
 
554
        __tablename__ = 'a'
 
555
 
 
556
        id = Column(Integer, primary_key=True)
 
557
 
 
558
    class B(A):
 
559
        __tablename__ = 'b'
 
560
 
 
561
        b_id = Column('id', Integer, primary_key=True)
 
562
        a_id = Column(Integer, ForeignKey('a.id'))
 
563
 
 
564
Suppose we did want ``A.id`` and ``B.id`` to be mirrors of each other, despite
 
565
the fact that ``B.a_id`` is where ``A.id`` is related.  We could combine
 
566
them together using :func:`.column_property`::
 
567
 
 
568
    class A(Base):
 
569
        __tablename__ = 'a'
 
570
 
 
571
        id = Column(Integer, primary_key=True)
 
572
 
 
573
    class B(A):
 
574
        __tablename__ = 'b'
 
575
 
 
576
        # probably not what you want, but this is a demonstration
 
577
        id = column_property(Column(Integer, primary_key=True), A.id)
 
578
        a_id = Column(Integer, ForeignKey('a.id'))
 
579
 
 
580
 
 
581
 
407
582
I'm using Declarative and setting primaryjoin/secondaryjoin using an ``and_()`` or ``or_()``, and I am getting an error message about foreign keys.
408
583
------------------------------------------------------------------------------------------------------------------------------------------------------------------
409
584
 
410
585
Are you doing this?::
411
586
 
412
 
        class MyClass(Base):
413
 
            # ....
 
587
    class MyClass(Base):
 
588
        # ....
414
589
 
415
 
            foo = relationship("Dest", primaryjoin=and_("MyClass.id==Dest.foo_id", "MyClass.foo==Dest.bar"))
 
590
        foo = relationship("Dest", primaryjoin=and_("MyClass.id==Dest.foo_id", "MyClass.foo==Dest.bar"))
416
591
 
417
592
That's an ``and_()`` of two string expressions, which SQLAlchemy cannot apply any mapping towards.  Declarative allows :func:`.relationship` arguments to be specified as strings, which are converted into expression objects using ``eval()``.   But this doesn't occur inside of an ``and_()`` expression - it's a special operation declarative applies only to the *entirety* of what's passed to primaryjoin or other arguments as a string::
418
593
 
419
 
        class MyClass(Base):
420
 
            # ....
 
594
    class MyClass(Base):
 
595
        # ....
421
596
 
422
 
            foo = relationship("Dest", primaryjoin="and_(MyClass.id==Dest.foo_id, MyClass.foo==Dest.bar)")
 
597
        foo = relationship("Dest", primaryjoin="and_(MyClass.id==Dest.foo_id, MyClass.foo==Dest.bar)")
423
598
 
424
599
Or if the objects you need are already available, skip the strings::
425
600
 
426
 
        class MyClass(Base):
427
 
            # ....
 
601
    class MyClass(Base):
 
602
        # ....
428
603
 
429
 
            foo = relationship(Dest, primaryjoin=and_(MyClass.id==Dest.foo_id, MyClass.foo==Dest.bar))
 
604
        foo = relationship(Dest, primaryjoin=and_(MyClass.id==Dest.foo_id, MyClass.foo==Dest.bar))
430
605
 
431
606
The same idea applies to all the other arguments, such as ``foreign_keys``::
432
607
 
433
 
        # wrong !
434
 
        foo = relationship(Dest, foreign_keys=["Dest.foo_id", "Dest.bar_id"])
435
 
 
436
 
        # correct !
437
 
        foo = relationship(Dest, foreign_keys="[Dest.foo_id, Dest.bar_id]")
438
 
 
439
 
        # also correct !
440
 
        foo = relationship(Dest, foreign_keys=[Dest.foo_id, Dest.bar_id])
441
 
 
442
 
        # if you're using columns from the class that you're inside of, just use the column objects !
443
 
        class MyClass(Base):
444
 
            foo_id = Column(...)
445
 
            bar_id = Column(...)
446
 
            # ...
447
 
 
448
 
            foo = relationship(Dest, foreign_keys=[foo_id, bar_id])
 
608
    # wrong !
 
609
    foo = relationship(Dest, foreign_keys=["Dest.foo_id", "Dest.bar_id"])
 
610
 
 
611
    # correct !
 
612
    foo = relationship(Dest, foreign_keys="[Dest.foo_id, Dest.bar_id]")
 
613
 
 
614
    # also correct !
 
615
    foo = relationship(Dest, foreign_keys=[Dest.foo_id, Dest.bar_id])
 
616
 
 
617
    # if you're using columns from the class that you're inside of, just use the column objects !
 
618
    class MyClass(Base):
 
619
        foo_id = Column(...)
 
620
        bar_id = Column(...)
 
621
        # ...
 
622
 
 
623
        foo = relationship(Dest, foreign_keys=[foo_id, bar_id])
 
624
 
 
625
Performance
 
626
===========
 
627
 
 
628
How can I profile a SQLAlchemy powered application?
 
629
---------------------------------------------------
 
630
 
 
631
Looking for performance issues typically involves two stratgies.  One
 
632
is query profiling, and the other is code profiling.
 
633
 
 
634
Query Profiling
 
635
^^^^^^^^^^^^^^^^
 
636
 
 
637
Sometimes just plain SQL logging (enabled via python's logging module
 
638
or via the ``echo=True`` argument on :func:`.create_engine`) can give an
 
639
idea how long things are taking.  For example, if you log something
 
640
right after a SQL operation, you'd see something like this in your
 
641
log::
 
642
 
 
643
    17:37:48,325 INFO  [sqlalchemy.engine.base.Engine.0x...048c] SELECT ...
 
644
    17:37:48,326 INFO  [sqlalchemy.engine.base.Engine.0x...048c] {<params>}
 
645
    17:37:48,660 DEBUG [myapp.somemessage]
 
646
 
 
647
if you logged ``myapp.somemessage`` right after the operation, you know
 
648
it took 334ms to complete the SQL part of things.
 
649
 
 
650
Logging SQL will also illustrate if dozens/hundreds of queries are
 
651
being issued which could be better organized into much fewer queries.
 
652
When using the SQLAlchemy ORM, the "eager loading"
 
653
feature is provided to partially (:func:`.contains_eager()`) or fully
 
654
(:func:`.joinedload()`, :func:`.subqueryload()`)
 
655
automate this activity, but without
 
656
the ORM "eager loading" typically means to use joins so that results across multiple
 
657
tables can be loaded in one result set instead of multiplying numbers
 
658
of queries as more depth is added (i.e. ``r + r*r2 + r*r2*r3`` ...)
 
659
 
 
660
For more long-term profiling of queries, or to implement an application-side
 
661
"slow query" monitor, events can be used to intercept cursor executions,
 
662
using a recipe like the following::
 
663
 
 
664
    from sqlalchemy import event
 
665
    from sqlalchemy.engine import Engine
 
666
    import time
 
667
    import logging
 
668
 
 
669
    logging.basicConfig()
 
670
    logger = logging.getLogger("myapp.sqltime")
 
671
    logger.setLevel(logging.DEBUG)
 
672
 
 
673
    @event.listens_for(Engine, "before_cursor_execute")
 
674
    def before_cursor_execute(conn, cursor, statement,
 
675
                            parameters, context, executemany):
 
676
        conn.info.setdefault('query_start_time', []).append(time.time())
 
677
        logger.debug("Start Query: %s" % statement)
 
678
 
 
679
    @event.listens_for(Engine, "after_cursor_execute")
 
680
    def after_cursor_execute(conn, cursor, statement,
 
681
                            parameters, context, executemany):
 
682
        total = time.time() - conn.info['query_start_time'].pop(-1)
 
683
        logger.debug("Query Complete!")
 
684
        logger.debug("Total Time: %f" % total)
 
685
 
 
686
Above, we use the :meth:`.ConnectionEvents.before_cursor_execute` and
 
687
:meth:`.ConnectionEvents.after_cursor_execute` events to establish an interception
 
688
point around when a statement is executed.  We attach a timer onto the
 
689
connection using the :class:`._ConnectionRecord.info` dictionary; we use a
 
690
stack here for the occasional case where the cursor execute events may be nested.
 
691
 
 
692
Code Profiling
 
693
^^^^^^^^^^^^^^
 
694
 
 
695
If logging reveals that individual queries are taking too long, you'd
 
696
need a breakdown of how much time was spent within the database
 
697
processing the query, sending results over the network, being handled
 
698
by the :term:`DBAPI`, and finally being received by SQLAlchemy's result set
 
699
and/or ORM layer.   Each of these stages can present their own
 
700
individual bottlenecks, depending on specifics.
 
701
 
 
702
For that you need to use the
 
703
`Python Profiling Module <https://docs.python.org/2/library/profile.html>`_.
 
704
Below is a simple recipe which works profiling into a context manager::
 
705
 
 
706
    import cProfile
 
707
    import StringIO
 
708
    import pstats
 
709
    import contextlib
 
710
 
 
711
    @contextlib.contextmanager
 
712
    def profiled():
 
713
        pr = cProfile.Profile()
 
714
        pr.enable()
 
715
        yield
 
716
        pr.disable()
 
717
        s = StringIO.StringIO()
 
718
        ps = pstats.Stats(pr, stream=s).sort_stats('cumulative')
 
719
        ps.print_stats()
 
720
        # uncomment this to see who's calling what
 
721
        # ps.print_callers()
 
722
        print s.getvalue()
 
723
 
 
724
To profile a section of code::
 
725
 
 
726
    with profiled():
 
727
        Session.query(FooClass).filter(FooClass.somevalue==8).all()
 
728
 
 
729
The output of profiling can be used to give an idea where time is
 
730
being spent.   A section of profiling output looks like this::
 
731
 
 
732
    13726 function calls (13042 primitive calls) in 0.014 seconds
 
733
 
 
734
    Ordered by: cumulative time
 
735
 
 
736
    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
 
737
    222/21    0.001    0.000    0.011    0.001 lib/sqlalchemy/orm/loading.py:26(instances)
 
738
    220/20    0.002    0.000    0.010    0.001 lib/sqlalchemy/orm/loading.py:327(_instance)
 
739
    220/20    0.000    0.000    0.010    0.000 lib/sqlalchemy/orm/loading.py:284(populate_state)
 
740
       20    0.000    0.000    0.010    0.000 lib/sqlalchemy/orm/strategies.py:987(load_collection_from_subq)
 
741
       20    0.000    0.000    0.009    0.000 lib/sqlalchemy/orm/strategies.py:935(get)
 
742
        1    0.000    0.000    0.009    0.009 lib/sqlalchemy/orm/strategies.py:940(_load)
 
743
       21    0.000    0.000    0.008    0.000 lib/sqlalchemy/orm/strategies.py:942(<genexpr>)
 
744
        2    0.000    0.000    0.004    0.002 lib/sqlalchemy/orm/query.py:2400(__iter__)
 
745
        2    0.000    0.000    0.002    0.001 lib/sqlalchemy/orm/query.py:2414(_execute_and_instances)
 
746
        2    0.000    0.000    0.002    0.001 lib/sqlalchemy/engine/base.py:659(execute)
 
747
        2    0.000    0.000    0.002    0.001 lib/sqlalchemy/sql/elements.py:321(_execute_on_connection)
 
748
        2    0.000    0.000    0.002    0.001 lib/sqlalchemy/engine/base.py:788(_execute_clauseelement)
 
749
 
 
750
    ...
 
751
 
 
752
Above, we can see that the ``instances()`` SQLAlchemy function was called 222
 
753
times (recursively, and 21 times from the outside), taking a total of .011
 
754
seconds for all calls combined.
 
755
 
 
756
Execution Slowness
 
757
^^^^^^^^^^^^^^^^^^
 
758
 
 
759
The specifics of these calls can tell us where the time is being spent.
 
760
If for example, you see time being spent within ``cursor.execute()``,
 
761
e.g. against the DBAPI::
 
762
 
 
763
    2    0.102    0.102    0.204    0.102 {method 'execute' of 'sqlite3.Cursor' objects}
 
764
 
 
765
this would indicate that the database is taking a long time to start returning
 
766
results, and it means your query should be optimized, either by adding indexes
 
767
or restructuring the query and/or underlying schema.  For that task,
 
768
analysis of the query plan is warranted, using a system such as EXPLAIN,
 
769
SHOW PLAN, etc. as is provided by the database backend.
 
770
 
 
771
Result Fetching Slowness - Core
 
772
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
773
 
 
774
If on the other hand you see many thousands of calls related to fetching rows,
 
775
or very long calls to ``fetchall()``, it may
 
776
mean your query is returning more rows than expected, or that the fetching
 
777
of rows itself is slow.   The ORM itself typically uses ``fetchall()`` to fetch
 
778
rows (or ``fetchmany()`` if the :meth:`.Query.yield_per` option is used).
 
779
 
 
780
An inordinately large number of rows would be indicated
 
781
by a very slow call to ``fetchall()`` at the DBAPI level::
 
782
 
 
783
    2    0.300    0.600    0.300    0.600 {method 'fetchall' of 'sqlite3.Cursor' objects}
 
784
 
 
785
An unexpectedly large number of rows, even if the ultimate result doesn't seem
 
786
to have many rows, can be the result of a cartesian product - when multiple
 
787
sets of rows are combined together without appropriately joining the tables
 
788
together.   It's often easy to produce this behavior with SQLAlchemy Core or
 
789
ORM query if the wrong :class:`.Column` objects are used in a complex query,
 
790
pulling in additional FROM clauses that are unexpected.
 
791
 
 
792
On the other hand, a fast call to ``fetchall()`` at the DBAPI level, but then
 
793
slowness when SQLAlchemy's :class:`.ResultProxy` is asked to do a ``fetchall()``,
 
794
may indicate slowness in processing of datatypes, such as unicode conversions
 
795
and similar::
 
796
 
 
797
    # the DBAPI cursor is fast...
 
798
    2    0.020    0.040    0.020    0.040 {method 'fetchall' of 'sqlite3.Cursor' objects}
 
799
 
 
800
    ...
 
801
 
 
802
    # but SQLAlchemy's result proxy is slow, this is type-level processing
 
803
    2    0.100    0.200    0.100    0.200 lib/sqlalchemy/engine/result.py:778(fetchall)
 
804
 
 
805
In some cases, a backend might be doing type-level processing that isn't
 
806
needed.   More specifically, seeing calls within the type API that are slow
 
807
are better indicators - below is what it looks like when we use a type like
 
808
this::
 
809
 
 
810
    from sqlalchemy import TypeDecorator
 
811
    import time
 
812
 
 
813
    class Foo(TypeDecorator):
 
814
        impl = String
 
815
 
 
816
        def process_result_value(self, value, thing):
 
817
            # intentionally add slowness for illustration purposes
 
818
            time.sleep(.001)
 
819
            return value
 
820
 
 
821
the profiling output of this intentionally slow operation can be seen like this::
 
822
 
 
823
      200    0.001    0.000    0.237    0.001 lib/sqlalchemy/sql/type_api.py:911(process)
 
824
      200    0.001    0.000    0.236    0.001 test.py:28(process_result_value)
 
825
      200    0.235    0.001    0.235    0.001 {time.sleep}
 
826
 
 
827
that is, we see many expensive calls within the ``type_api`` system, and the actual
 
828
time consuming thing is the ``time.sleep()`` call.
 
829
 
 
830
Make sure to check the :doc:`Dialect documentation <dialects/index>`
 
831
for notes on known performance tuning suggestions at this level, especially for
 
832
databases like Oracle.  There may be systems related to ensuring numeric accuracy
 
833
or string processing that may not be needed in all cases.
 
834
 
 
835
There also may be even more low-level points at which row-fetching performance is suffering;
 
836
for example, if time spent seems to focus on a call like ``socket.receive()``,
 
837
that could indicate that everything is fast except for the actual network connection,
 
838
and too much time is spent with data moving over the network.
 
839
 
 
840
Result Fetching Slowness - ORM
 
841
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
842
 
 
843
To detect slowness in ORM fetching of rows (which is the most common area
 
844
of performance concern), calls like ``populate_state()`` and ``_instance()`` will
 
845
illustrate individual ORM object populations::
 
846
 
 
847
    # the ORM calls _instance for each ORM-loaded row it sees, and
 
848
    # populate_state for each ORM-loaded row that results in the population
 
849
    # of an object's attributes
 
850
    220/20    0.001    0.000    0.010    0.000 lib/sqlalchemy/orm/loading.py:327(_instance)
 
851
    220/20    0.000    0.000    0.009    0.000 lib/sqlalchemy/orm/loading.py:284(populate_state)
 
852
 
 
853
The ORM's slowness in turning rows into ORM-mapped objects is a product
 
854
of the complexity of this operation combined with the overhead of cPython.
 
855
Common strategies to mitigate this include:
 
856
 
 
857
* fetch individual columns instead of full entities, that is::
 
858
 
 
859
      session.query(User.id, User.name)
 
860
 
 
861
  instead of::
 
862
 
 
863
      session.query(User)
 
864
 
 
865
* Use :class:`.Bundle` objects to organize column-based results::
 
866
 
 
867
      u_b = Bundle('user', User.id, User.name)
 
868
      a_b = Bundle('address', Address.id, Address.email)
 
869
 
 
870
      for user, address in session.query(u_b, a_b).join(User.addresses):
 
871
          # ...
 
872
 
 
873
* Use result caching - see :ref:`examples_caching` for an in-depth example
 
874
  of this.
 
875
 
 
876
* Consider a faster interpreter like that of Pypy.
 
877
 
 
878
The output of a profile can be a little daunting but after some
 
879
practice they are very easy to read.
 
880
 
 
881
If you're feeling ambitious, there's also a more involved example of
 
882
SQLAlchemy profiling within the SQLAlchemy unit tests in the
 
883
``tests/aaa_profiling`` section.  Tests in this area
 
884
use decorators that assert a
 
885
maximum number of method calls being used for particular operations,
 
886
so that if something inefficient gets checked in, the tests will
 
887
reveal it (it is important to note that in cPython, function calls have
 
888
the highest overhead of any operation, and the count of calls is more
 
889
often than not nearly proportional to time spent).   Of note are the
 
890
the "zoomark" tests which use a fancy "SQL capturing" scheme which
 
891
cuts out the overhead of the DBAPI from the equation - although that
 
892
technique isn't really necessary for garden-variety profiling.
 
893
 
 
894
I'm inserting 400,000 rows with the ORM and it's really slow!
 
895
--------------------------------------------------------------
 
896
 
 
897
The SQLAlchemy ORM uses the :term:`unit of work` pattern when synchronizing
 
898
changes to the database. This pattern goes far beyond simple "inserts"
 
899
of data. It includes that attributes which are assigned on objects are
 
900
received using an attribute instrumentation system which tracks
 
901
changes on objects as they are made, includes that all rows inserted
 
902
are tracked in an identity map which has the effect that for each row
 
903
SQLAlchemy must retrieve its "last inserted id" if not already given,
 
904
and also involves that rows to be inserted are scanned and sorted for
 
905
dependencies as needed. Objects are also subject to a fair degree of
 
906
bookkeeping in order to keep all of this running, which for a very
 
907
large number of rows at once can create an inordinate amount of time
 
908
spent with large data structures, hence it's best to chunk these.
 
909
 
 
910
Basically, unit of work is a large degree of automation in order to
 
911
automate the task of persisting a complex object graph into a
 
912
relational database with no explicit persistence code, and this
 
913
automation has a price.
 
914
 
 
915
ORMs are basically not intended for high-performance bulk inserts -
 
916
this is the whole reason SQLAlchemy offers the Core in addition to the
 
917
ORM as a first-class component.
 
918
 
 
919
For the use case of fast bulk inserts, the
 
920
SQL generation and execution system that the ORM builds on top of
 
921
is part of the Core.  Using this system directly, we can produce an INSERT that
 
922
is competitive with using the raw database API directly.
 
923
 
 
924
The example below illustrates time-based tests for four different
 
925
methods of inserting rows, going from the most automated to the least.
 
926
With cPython 2.7, runtimes observed::
 
927
 
 
928
    classics-MacBook-Pro:sqlalchemy classic$ python test.py
 
929
    SQLAlchemy ORM: Total time for 100000 records 14.3528850079 secs
 
930
    SQLAlchemy ORM pk given: Total time for 100000 records 10.0164160728 secs
 
931
    SQLAlchemy Core: Total time for 100000 records 0.775382995605 secs
 
932
    sqlite3: Total time for 100000 records 0.676795005798 sec
 
933
 
 
934
We can reduce the time by a factor of three using recent versions of `Pypy <http://pypy.org/>`_::
 
935
 
 
936
    classics-MacBook-Pro:sqlalchemy classic$ /usr/local/src/pypy-2.1-beta2-osx64/bin/pypy test.py
 
937
    SQLAlchemy ORM: Total time for 100000 records 5.88369488716 secs
 
938
    SQLAlchemy ORM pk given: Total time for 100000 records 3.52294301987 secs
 
939
    SQLAlchemy Core: Total time for 100000 records 0.613556146622 secs
 
940
    sqlite3: Total time for 100000 records 0.442467927933 sec
 
941
 
 
942
Script::
 
943
 
 
944
    import time
 
945
    import sqlite3
 
946
 
 
947
    from sqlalchemy.ext.declarative import declarative_base
 
948
    from sqlalchemy import Column, Integer, String,  create_engine
 
949
    from sqlalchemy.orm import scoped_session, sessionmaker
 
950
 
 
951
    Base = declarative_base()
 
952
    DBSession = scoped_session(sessionmaker())
 
953
    engine = None
 
954
 
 
955
    class Customer(Base):
 
956
        __tablename__ = "customer"
 
957
        id = Column(Integer, primary_key=True)
 
958
        name = Column(String(255))
 
959
 
 
960
    def init_sqlalchemy(dbname='sqlite:///sqlalchemy.db'):
 
961
        global engine
 
962
        engine = create_engine(dbname, echo=False)
 
963
        DBSession.remove()
 
964
        DBSession.configure(bind=engine, autoflush=False, expire_on_commit=False)
 
965
        Base.metadata.drop_all(engine)
 
966
        Base.metadata.create_all(engine)
 
967
 
 
968
    def test_sqlalchemy_orm(n=100000):
 
969
        init_sqlalchemy()
 
970
        t0 = time.time()
 
971
        for i in range(n):
 
972
            customer = Customer()
 
973
            customer.name = 'NAME ' + str(i)
 
974
            DBSession.add(customer)
 
975
            if i % 1000 == 0:
 
976
                DBSession.flush()
 
977
        DBSession.commit()
 
978
        print("SQLAlchemy ORM: Total time for " + str(n) +
 
979
                    " records " + str(time.time() - t0) + " secs")
 
980
 
 
981
    def test_sqlalchemy_orm_pk_given(n=100000):
 
982
        init_sqlalchemy()
 
983
        t0 = time.time()
 
984
        for i in range(n):
 
985
            customer = Customer(id=i+1, name="NAME " + str(i))
 
986
            DBSession.add(customer)
 
987
            if i % 1000 == 0:
 
988
                DBSession.flush()
 
989
        DBSession.commit()
 
990
        print("SQLAlchemy ORM pk given: Total time for " + str(n) +
 
991
            " records " + str(time.time() - t0) + " secs")
 
992
 
 
993
    def test_sqlalchemy_core(n=100000):
 
994
        init_sqlalchemy()
 
995
        t0 = time.time()
 
996
        engine.execute(
 
997
            Customer.__table__.insert(),
 
998
            [{"name": 'NAME ' + str(i)} for i in range(n)]
 
999
        )
 
1000
        print("SQLAlchemy Core: Total time for " + str(n) +
 
1001
            " records " + str(time.time() - t0) + " secs")
 
1002
 
 
1003
    def init_sqlite3(dbname):
 
1004
        conn = sqlite3.connect(dbname)
 
1005
        c = conn.cursor()
 
1006
        c.execute("DROP TABLE IF EXISTS customer")
 
1007
        c.execute("CREATE TABLE customer (id INTEGER NOT NULL, "
 
1008
                                    "name VARCHAR(255), PRIMARY KEY(id))")
 
1009
        conn.commit()
 
1010
        return conn
 
1011
 
 
1012
    def test_sqlite3(n=100000, dbname='sqlite3.db'):
 
1013
        conn = init_sqlite3(dbname)
 
1014
        c = conn.cursor()
 
1015
        t0 = time.time()
 
1016
        for i in range(n):
 
1017
            row = ('NAME ' + str(i),)
 
1018
            c.execute("INSERT INTO customer (name) VALUES (?)", row)
 
1019
        conn.commit()
 
1020
        print("sqlite3: Total time for " + str(n) +
 
1021
            " records " + str(time.time() - t0) + " sec")
 
1022
 
 
1023
    if __name__ == '__main__':
 
1024
        test_sqlalchemy_orm(100000)
 
1025
        test_sqlalchemy_orm_pk_given(100000)
 
1026
        test_sqlalchemy_core(100000)
 
1027
        test_sqlite3(100000)
 
1028
 
449
1029
 
450
1030
 
451
1031
Sessions / Queries
452
1032
===================
453
1033
 
 
1034
 
454
1035
"This Session's transaction has been rolled back due to a previous exception during flush." (or similar)
455
1036
---------------------------------------------------------------------------------------------------------
456
1037
 
462
1043
upon :meth:`.Session.flush` or :meth:`.Session.commit` and
463
1044
does not properly handle the exception.    For example::
464
1045
 
465
 
        from sqlalchemy import create_engine, Column, Integer
466
 
        from sqlalchemy.orm import sessionmaker
467
 
        from sqlalchemy.ext.declarative import declarative_base
468
 
 
469
 
        Base = declarative_base(create_engine('sqlite://'))
470
 
 
471
 
        class Foo(Base):
472
 
            __tablename__ = 'foo'
473
 
            id = Column(Integer, primary_key=True)
474
 
 
475
 
        Base.metadata.create_all()
476
 
 
477
 
        session = sessionmaker()()
478
 
 
479
 
        # constraint violation
480
 
        session.add_all([Foo(id=1), Foo(id=1)])
481
 
 
482
 
        try:
483
 
            session.commit()
484
 
        except:
485
 
            # ignore error
486
 
            pass
487
 
 
488
 
        # continue using session without rolling back
489
 
        session.commit()
 
1046
    from sqlalchemy import create_engine, Column, Integer
 
1047
    from sqlalchemy.orm import sessionmaker
 
1048
    from sqlalchemy.ext.declarative import declarative_base
 
1049
 
 
1050
    Base = declarative_base(create_engine('sqlite://'))
 
1051
 
 
1052
    class Foo(Base):
 
1053
        __tablename__ = 'foo'
 
1054
        id = Column(Integer, primary_key=True)
 
1055
 
 
1056
    Base.metadata.create_all()
 
1057
 
 
1058
    session = sessionmaker()()
 
1059
 
 
1060
    # constraint violation
 
1061
    session.add_all([Foo(id=1), Foo(id=1)])
 
1062
 
 
1063
    try:
 
1064
        session.commit()
 
1065
    except:
 
1066
        # ignore error
 
1067
        pass
 
1068
 
 
1069
    # continue using session without rolling back
 
1070
    session.commit()
490
1071
 
491
1072
 
492
1073
The usage of the :class:`.Session` should fit within a structure similar to this::
493
1074
 
494
 
        try:
495
 
            <use session>
496
 
            session.commit()
497
 
        except:
498
 
           session.rollback()
499
 
           raise
500
 
        finally:
501
 
           session.close()  # optional, depends on use case
 
1075
    try:
 
1076
        <use session>
 
1077
        session.commit()
 
1078
    except:
 
1079
       session.rollback()
 
1080
       raise
 
1081
    finally:
 
1082
       session.close()  # optional, depends on use case
502
1083
 
503
1084
Many things can cause a failure within the try/except besides flushes. You
504
1085
should always have some kind of "framing" of your session operations so that
524
1105
case. Postgres in particular has operations which, once failed, the
525
1106
transaction is not allowed to continue::
526
1107
 
527
 
        test=> create table foo(id integer primary key);
528
 
        NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
529
 
        CREATE TABLE
530
 
        test=> begin;
531
 
        BEGIN
532
 
        test=> insert into foo values(1);
533
 
        INSERT 0 1
534
 
        test=> commit;
535
 
        COMMIT
536
 
        test=> begin;
537
 
        BEGIN
538
 
        test=> insert into foo values(1);
539
 
        ERROR:  duplicate key value violates unique constraint "foo_pkey"
540
 
        test=> insert into foo values(2);
541
 
        ERROR:  current transaction is aborted, commands ignored until end of transaction block
 
1108
    test=> create table foo(id integer primary key);
 
1109
    NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
 
1110
    CREATE TABLE
 
1111
    test=> begin;
 
1112
    BEGIN
 
1113
    test=> insert into foo values(1);
 
1114
    INSERT 0 1
 
1115
    test=> commit;
 
1116
    COMMIT
 
1117
    test=> begin;
 
1118
    BEGIN
 
1119
    test=> insert into foo values(1);
 
1120
    ERROR:  duplicate key value violates unique constraint "foo_pkey"
 
1121
    test=> insert into foo values(2);
 
1122
    ERROR:  current transaction is aborted, commands ignored until end of transaction block
542
1123
 
543
1124
What SQLAlchemy offers that solves both issues is support of SAVEPOINT, via
544
1125
:meth:`.Session.begin_nested`. Using :meth:`.Session.begin_nested`, you can frame an operation that may
553
1134
:class:`.Session` supports "framing" above within multiple levels. Such as, suppose
554
1135
you had a decorator ``@with_session()``, which did this::
555
1136
 
556
 
        def with_session(fn):
557
 
           def go(*args, **kw):
558
 
               session.begin(subtransactions=True)
559
 
               try:
560
 
                   ret = fn(*args, **kw)
561
 
                   session.commit()
562
 
                   return ret
563
 
               except:
564
 
                   session.rollback()
565
 
                   raise
566
 
           return go
 
1137
    def with_session(fn):
 
1138
       def go(*args, **kw):
 
1139
           session.begin(subtransactions=True)
 
1140
           try:
 
1141
               ret = fn(*args, **kw)
 
1142
               session.commit()
 
1143
               return ret
 
1144
           except:
 
1145
               session.rollback()
 
1146
               raise
 
1147
       return go
567
1148
 
568
1149
The above decorator begins a transaction if one does not exist already, and
569
1150
then commits it, if it were the creator. The "subtransactions" flag means that
572
1153
is called and only when it goes back to zero does the actual COMMIT happen. It
573
1154
allows this usage pattern::
574
1155
 
575
 
        @with_session
576
 
        def one():
577
 
           # do stuff
578
 
           two()
579
 
 
580
 
 
581
 
        @with_session
582
 
        def two():
583
 
           # etc.
584
 
 
585
 
        one()
586
 
 
587
 
        two()
 
1156
    @with_session
 
1157
    def one():
 
1158
       # do stuff
 
1159
       two()
 
1160
 
 
1161
 
 
1162
    @with_session
 
1163
    def two():
 
1164
       # etc.
 
1165
 
 
1166
    one()
 
1167
 
 
1168
    two()
588
1169
 
589
1170
``one()`` can call ``two()``, or ``two()`` can be called by itself, and the
590
1171
``@with_session`` decorator ensures the appropriate "framing" - the transaction
621
1202
starting/ending the "frame" is kept consistently with the code external to the
622
1203
``flush()``, and we made a decision that this was the most consistent approach.
623
1204
 
624
 
I'm inserting 400,000 rows with the ORM and it's really slow!
625
 
--------------------------------------------------------------
626
 
 
627
 
The SQLAlchemy ORM uses the :term:`unit of work` pattern when synchronizing
628
 
changes to the database. This pattern goes far beyond simple "inserts"
629
 
of data. It includes that attributes which are assigned on objects are
630
 
received using an attribute instrumentation system which tracks
631
 
changes on objects as they are made, includes that all rows inserted
632
 
are tracked in an identity map which has the effect that for each row
633
 
SQLAlchemy must retrieve its "last inserted id" if not already given,
634
 
and also involves that rows to be inserted are scanned and sorted for
635
 
dependencies as needed. Objects are also subject to a fair degree of
636
 
bookkeeping in order to keep all of this running, which for a very
637
 
large number of rows at once can create an inordinate amount of time
638
 
spent with large data structures, hence it's best to chunk these.
639
 
 
640
 
Basically, unit of work is a large degree of automation in order to
641
 
automate the task of persisting a complex object graph into a
642
 
relational database with no explicit persistence code, and this
643
 
automation has a price.
644
 
 
645
 
ORMs are basically not intended for high-performance bulk inserts -
646
 
this is the whole reason SQLAlchemy offers the Core in addition to the
647
 
ORM as a first-class component.
648
 
 
649
 
For the use case of fast bulk inserts, the
650
 
SQL generation and execution system that the ORM builds on top of
651
 
is part of the Core.  Using this system directly, we can produce an INSERT that
652
 
is competitive with using the raw database API directly.
653
 
 
654
 
The example below illustrates time-based tests for four different
655
 
methods of inserting rows, going from the most automated to the least.
656
 
With cPython 2.7, runtimes observed::
657
 
 
658
 
        classics-MacBook-Pro:sqlalchemy classic$ python test.py
659
 
        SQLAlchemy ORM: Total time for 100000 records 14.3528850079 secs
660
 
        SQLAlchemy ORM pk given: Total time for 100000 records 10.0164160728 secs
661
 
        SQLAlchemy Core: Total time for 100000 records 0.775382995605 secs
662
 
        sqlite3: Total time for 100000 records 0.676795005798 sec
663
 
 
664
 
We can reduce the time by a factor of three using recent versions of `Pypy <http://pypy.org/>`_::
665
 
 
666
 
        classics-MacBook-Pro:sqlalchemy classic$ /usr/local/src/pypy-2.1-beta2-osx64/bin/pypy test.py
667
 
        SQLAlchemy ORM: Total time for 100000 records 5.88369488716 secs
668
 
        SQLAlchemy ORM pk given: Total time for 100000 records 3.52294301987 secs
669
 
        SQLAlchemy Core: Total time for 100000 records 0.613556146622 secs
670
 
        sqlite3: Total time for 100000 records 0.442467927933 sec
671
 
 
672
 
Script::
673
 
 
674
 
        import time
675
 
        import sqlite3
676
 
 
677
 
        from sqlalchemy.ext.declarative import declarative_base
678
 
        from sqlalchemy import Column, Integer, String,  create_engine
679
 
        from sqlalchemy.orm import scoped_session, sessionmaker
680
 
 
681
 
        Base = declarative_base()
682
 
        DBSession = scoped_session(sessionmaker())
683
 
        engine = None
684
 
 
685
 
        class Customer(Base):
686
 
            __tablename__ = "customer"
687
 
            id = Column(Integer, primary_key=True)
688
 
            name = Column(String(255))
689
 
 
690
 
        def init_sqlalchemy(dbname='sqlite:///sqlalchemy.db'):
691
 
            global engine
692
 
            engine = create_engine(dbname, echo=False)
693
 
            DBSession.remove()
694
 
            DBSession.configure(bind=engine, autoflush=False, expire_on_commit=False)
695
 
            Base.metadata.drop_all(engine)
696
 
            Base.metadata.create_all(engine)
697
 
 
698
 
        def test_sqlalchemy_orm(n=100000):
699
 
            init_sqlalchemy()
700
 
            t0 = time.time()
701
 
            for i in range(n):
702
 
                customer = Customer()
703
 
                customer.name = 'NAME ' + str(i)
704
 
                DBSession.add(customer)
705
 
                if i % 1000 == 0:
706
 
                    DBSession.flush()
707
 
            DBSession.commit()
708
 
            print("SQLAlchemy ORM: Total time for " + str(n) +
709
 
                        " records " + str(time.time() - t0) + " secs")
710
 
 
711
 
        def test_sqlalchemy_orm_pk_given(n=100000):
712
 
            init_sqlalchemy()
713
 
            t0 = time.time()
714
 
            for i in range(n):
715
 
                customer = Customer(id=i+1, name="NAME " + str(i))
716
 
                DBSession.add(customer)
717
 
                if i % 1000 == 0:
718
 
                    DBSession.flush()
719
 
            DBSession.commit()
720
 
            print("SQLAlchemy ORM pk given: Total time for " + str(n) +
721
 
                " records " + str(time.time() - t0) + " secs")
722
 
 
723
 
        def test_sqlalchemy_core(n=100000):
724
 
            init_sqlalchemy()
725
 
            t0 = time.time()
726
 
            engine.execute(
727
 
                Customer.__table__.insert(),
728
 
                [{"name": 'NAME ' + str(i)} for i in range(n)]
729
 
            )
730
 
            print("SQLAlchemy Core: Total time for " + str(n) +
731
 
                " records " + str(time.time() - t0) + " secs")
732
 
 
733
 
        def init_sqlite3(dbname):
734
 
            conn = sqlite3.connect(dbname)
735
 
            c = conn.cursor()
736
 
            c.execute("DROP TABLE IF EXISTS customer")
737
 
            c.execute("CREATE TABLE customer (id INTEGER NOT NULL, "
738
 
                                        "name VARCHAR(255), PRIMARY KEY(id))")
739
 
            conn.commit()
740
 
            return conn
741
 
 
742
 
        def test_sqlite3(n=100000, dbname='sqlite3.db'):
743
 
            conn = init_sqlite3(dbname)
744
 
            c = conn.cursor()
745
 
            t0 = time.time()
746
 
            for i in range(n):
747
 
                row = ('NAME ' + str(i),)
748
 
                c.execute("INSERT INTO customer (name) VALUES (?)", row)
749
 
            conn.commit()
750
 
            print("sqlite3: Total time for " + str(n) +
751
 
                " records " + str(time.time() - t0) + " sec")
752
 
 
753
 
        if __name__ == '__main__':
754
 
            test_sqlalchemy_orm(100000)
755
 
            test_sqlalchemy_orm_pk_given(100000)
756
 
            test_sqlalchemy_core(100000)
757
 
            test_sqlite3(100000)
758
 
 
759
1205
 
760
1206
 
761
1207
How do I make a Query that always adds a certain filter to every query?
793
1239
because evaluating the query as a list would incur two SQL calls instead of
794
1240
one::
795
1241
 
796
 
        class Iterates(object):
797
 
            def __len__(self):
798
 
                print "LEN!"
799
 
                return 5
800
 
 
801
 
            def __iter__(self):
802
 
                print "ITER!"
803
 
                return iter([1, 2, 3, 4, 5])
804
 
 
805
 
        list(Iterates())
 
1242
    class Iterates(object):
 
1243
        def __len__(self):
 
1244
            print "LEN!"
 
1245
            return 5
 
1246
 
 
1247
        def __iter__(self):
 
1248
            print "ITER!"
 
1249
            return iter([1, 2, 3, 4, 5])
 
1250
 
 
1251
    list(Iterates())
806
1252
 
807
1253
output::
808
1254
 
809
 
        ITER!
810
 
        LEN!
 
1255
    ITER!
 
1256
    LEN!
811
1257
 
812
1258
How Do I use Textual SQL with ORM Queries?
813
1259
-------------------------------------------
823
1269
 
824
1270
See :ref:`session_deleting_from_collections` for a description of this behavior.
825
1271
 
826
 
why isnt my ``__init__()`` called when I load objects?
827
 
------------------------------------------------------
 
1272
why isn't my ``__init__()`` called when I load objects?
 
1273
-------------------------------------------------------
828
1274
 
829
1275
See :ref:`mapping_constructors` for a description of this behavior.
830
1276
 
850
1296
relationships naturally. Therefore, the recommended way to
851
1297
set ``o.foo`` is to do just that - set it!::
852
1298
 
853
 
        foo = Session.query(Foo).get(7)
854
 
        o.foo = foo
855
 
        Session.commit()
 
1299
    foo = Session.query(Foo).get(7)
 
1300
    o.foo = foo
 
1301
    Session.commit()
856
1302
 
857
1303
Manipulation of foreign key attributes is of course entirely legal.  However,
858
1304
setting a foreign-key attribute to a new value currently does not trigger
859
1305
an "expire" event of the :func:`.relationship` in which it's involved.  This means
860
1306
that for the following sequence::
861
1307
 
862
 
        o = Session.query(SomeClass).first()
863
 
        assert o.foo is None  # accessing an un-set attribute sets it to None
864
 
        o.foo_id = 7
 
1308
    o = Session.query(SomeClass).first()
 
1309
    assert o.foo is None  # accessing an un-set attribute sets it to None
 
1310
    o.foo_id = 7
865
1311
 
866
1312
``o.foo`` is initialized to ``None`` when we first accessed it.  Setting
867
1313
``o.foo_id = 7`` will have the value of "7" as pending, but no flush
868
1314
has occurred - so ``o.foo`` is still ``None``::
869
1315
 
870
 
        # attribute is already set to None, has not been
871
 
        # reconciled with o.foo_id = 7 yet
872
 
        assert o.foo is None
 
1316
    # attribute is already set to None, has not been
 
1317
    # reconciled with o.foo_id = 7 yet
 
1318
    assert o.foo is None
873
1319
 
874
1320
For ``o.foo`` to load based on the foreign key mutation is usually achieved
875
1321
naturally after the commit, which both flushes the new foreign key value
876
1322
and expires all state::
877
1323
 
878
 
        Session.commit()  # expires all attributes
879
 
 
880
 
        foo_7 = Session.query(Foo).get(7)
881
 
 
882
 
        assert o.foo is foo_7  # o.foo lazyloads on access
 
1324
    Session.commit()  # expires all attributes
 
1325
 
 
1326
    foo_7 = Session.query(Foo).get(7)
 
1327
 
 
1328
    assert o.foo is foo_7  # o.foo lazyloads on access
883
1329
 
884
1330
A more minimal operation is to expire the attribute individually - this can
885
1331
be performed for any :term:`persistent` object using :meth:`.Session.expire`::
886
1332
 
887
 
        o = Session.query(SomeClass).first()
888
 
        o.foo_id = 7
889
 
        Session.expire(o, ['foo'])  # object must be persistent for this
890
 
 
891
 
        foo_7 = Session.query(Foo).get(7)
892
 
 
893
 
        assert o.foo is foo_7  # o.foo lazyloads on access
 
1333
    o = Session.query(SomeClass).first()
 
1334
    o.foo_id = 7
 
1335
    Session.expire(o, ['foo'])  # object must be persistent for this
 
1336
 
 
1337
    foo_7 = Session.query(Foo).get(7)
 
1338
 
 
1339
    assert o.foo is foo_7  # o.foo lazyloads on access
894
1340
 
895
1341
Note that if the object is not persistent but present in the :class:`.Session`,
896
1342
it's known as :term:`pending`.   This means the row for the object has not been
897
1343
INSERTed into the database yet.  For such an object, setting ``foo_id`` does not
898
1344
have meaning until the row is inserted; otherwise there is no row yet::
899
1345
 
900
 
        new_obj = SomeClass()
901
 
        new_obj.foo_id = 7
902
 
 
903
 
        Session.add(new_obj)
904
 
 
905
 
        # accessing an un-set attribute sets it to None
906
 
        assert new_obj.foo is None
907
 
 
908
 
        Session.flush()  # emits INSERT
909
 
 
910
 
        # expire this because we already set .foo to None
911
 
        Session.expire(o, ['foo'])
912
 
 
913
 
        assert new_obj.foo is foo_7  # now it loads
 
1346
    new_obj = SomeClass()
 
1347
    new_obj.foo_id = 7
 
1348
 
 
1349
    Session.add(new_obj)
 
1350
 
 
1351
    # accessing an un-set attribute sets it to None
 
1352
    assert new_obj.foo is None
 
1353
 
 
1354
    Session.flush()  # emits INSERT
 
1355
 
 
1356
    # expire this because we already set .foo to None
 
1357
    Session.expire(o, ['foo'])
 
1358
 
 
1359
    assert new_obj.foo is foo_7  # now it loads
914
1360
 
915
1361
 
916
1362
.. topic:: Attribute loading for non-persistent objects
917
1363
 
918
 
        One variant on the "pending" behavior above is if we use the flag
919
 
        ``load_on_pending`` on :func:`.relationship`.   When this flag is set, the
920
 
        lazy loader will emit for ``new_obj.foo`` before the INSERT proceeds; another
921
 
        variant of this is to use the :meth:`.Session.enable_relationship_loading`
922
 
        method, which can "attach" an object to a :class:`.Session` in such a way that
923
 
        many-to-one relationships load as according to foreign key attributes
924
 
        regardless of the object being in any particular state.
925
 
        Both techniques are **not recommended for general use**; they were added to suit
926
 
        specfic programming scenarios encountered by users which involve the repurposing
927
 
        of the ORM's usual object states.
 
1364
    One variant on the "pending" behavior above is if we use the flag
 
1365
    ``load_on_pending`` on :func:`.relationship`.   When this flag is set, the
 
1366
    lazy loader will emit for ``new_obj.foo`` before the INSERT proceeds; another
 
1367
    variant of this is to use the :meth:`.Session.enable_relationship_loading`
 
1368
    method, which can "attach" an object to a :class:`.Session` in such a way that
 
1369
    many-to-one relationships load as according to foreign key attributes
 
1370
    regardless of the object being in any particular state.
 
1371
    Both techniques are **not recommended for general use**; they were added to suit
 
1372
    specific programming scenarios encountered by users which involve the repurposing
 
1373
    of the ORM's usual object states.
928
1374
 
929
1375
The recipe `ExpireRelationshipOnFKChange <http://www.sqlalchemy.org/trac/wiki/UsageRecipes/ExpireRelationshipOnFKChange>`_ features an example using SQLAlchemy events
930
1376
in order to coordinate the setting of foreign key attributes with many-to-one