object internally. See :ref:`unitofwork_transaction` for further
information.
-The :class:`~sqlalchemy.engine.base.Connection` object provides a ``begin()``
-method which returns a :class:`~sqlalchemy.engine.base.Transaction` object.
+The :class:`~sqlalchemy.engine.Connection` object provides a :meth:`~.Connection.begin`
+method which returns a :class:`.Transaction` object.
This object is usually used within a try/except clause so that it is
-guaranteed to ``rollback()`` or ``commit()``::
+guaranteed to invoke :meth:`.Transaction.rollback` or :meth:`.Transaction.commit`::
+ connection = engine.connect()
trans = connection.begin()
try:
r1 = connection.execute(table1.select())
trans.rollback()
raise
+The above block can be created more succinctly using context
+managers, either given an :class:`.Engine`::
+
+ # runs a transaction
+ with engine.begin() as connection:
+ r1 = connection.execute(table1.select())
+ connection.execute(table1.insert(), col1=7, col2='this is some data')
+
+Or from the :class:`.Connection`, in which case the :class:`.Transaction` object
+is available as well::
+
+ with connection.begin() as trans:
+ r1 = connection.execute(table1.select())
+ connection.execute(table1.insert(), col1=7, col2='this is some data')
+
.. _connections_nested_transactions:
Nesting of Transaction Blocks
------------------------------
-The :class:`~sqlalchemy.engine.base.Transaction` object also handles "nested"
+The :class:`.Transaction` object also handles "nested"
behavior by keeping track of the outermost begin/commit pair. In this example,
-two functions both issue a transaction on a Connection, but only the outermost
-Transaction object actually takes effect when it is committed.
+two functions both issue a transaction on a :class:`.Connection`, but only the outermost
+:class:`.Transaction` object actually takes effect when it is committed.
.. sourcecode:: python+sql
usage of :class:`.Connection`. "Connectionless" execution
refers to the usage of the ``execute()`` method on an object which is not a
:class:`.Connection`. This was illustrated using the :meth:`~.Engine.execute` method
-of :class:`.Engine`.
+of :class:`.Engine`::
+
+ result = engine.execute("select username from users")
+ for row in result:
+ print "username:", row['username']
In addition to "connectionless" execution, it is also possible
to use the :meth:`~.Executable.execute` method of
Given a table as below::
+ from sqlalchemy import MetaData, Table, Column, Integer
+
meta = MetaData()
users_table = Table('users', meta,
Column('id', Integer, primary_key=True),
)
Explicit execution delivers the SQL text or constructed SQL expression to the
-``execute()`` method of :class:`~sqlalchemy.engine.base.Connection`:
+:meth:`~.Connection.execute` method of :class:`~sqlalchemy.engine.Connection`:
.. sourcecode:: python+sql
connection.close()
Explicit, connectionless execution delivers the expression to the
-``execute()`` method of :class:`~sqlalchemy.engine.base.Engine`:
+:meth:`~.Engine.execute` method of :class:`~sqlalchemy.engine.Engine`:
.. sourcecode:: python+sql
# ....
result.close()
-Implicit execution is also connectionless, and calls the ``execute()`` method
-on the expression itself, utilizing the fact that either an
-:class:`~sqlalchemy.engine.base.Engine` or
-:class:`~sqlalchemy.engine.base.Connection` has been *bound* to the expression
-object (binding is discussed further in
-:ref:`metadata_toplevel`):
-
-.. sourcecode:: python+sql
+Implicit execution is also connectionless, and makes usage of the :meth:`~.Executable.execute` method
+on the expression itself. This method is provided as part of the
+:class:`.Executable` class, which refers to a SQL statement that is sufficient
+for being invoked against the database. The method makes usage of
+the assumption that either an
+:class:`~sqlalchemy.engine.Engine` or
+:class:`~sqlalchemy.engine.Connection` has been **bound** to the expression
+object. By "bound" we mean that the special attribute :attr:`.MetaData.bind`
+has been used to associate a series of
+:class:`.Table` objects and all SQL constructs derived from them with a specific
+engine::
engine = create_engine('sqlite:///file.db')
meta.bind = engine
# ....
result.close()
+Above, we associate an :class:`.Engine` with a :class:`.MetaData` object using
+the special attribute :attr:`.MetaData.bind`. The :func:`.select` construct produced
+from the :class:`.Table` object has a method :meth:`~.Executable.execute`, which will
+search for an :class:`.Engine` that's "bound" to the :class:`.Table`.
+
+.. note::
+
+ The concepts of "bound metadata" and "implicit execution" are not emphasized in modern SQLAlchemy.
+ In applications
+ where multiple :class:`.Engine` objects are present, each one logically associated
+ with a certain set of tables (i.e. *vertical sharding*), the "bound metadata" technique can be used
+ so that individual :class:`.Table` can refer to the appropriate :class:`.Engine` automatically;
+ in particular this is supported within the ORM via the :class:`.Session` object
+ as a means to associate :class:`.Table` objects with an appropriate :class:`.Engine`,
+ as an alternative to using the bind arguments accepted directly by the :class:`.Session`.
+ However, the "implicit execution" technique is not at all appropriate for use with the
+ ORM, as it bypasses the transactional context maintained by the :class:`.Session`.
+
+ Overall, in the *vast majority* of cases, "bound metadata" and "implicit execution"
+ are **not useful**. While "bound metadata" has a marginal level of usefulness with regards to
+ ORM configuration, "implicit execution" is a very old usage pattern that in most
+ cases is more confusing than it is helpful, and its usage is discouraged.
+
+ Modern SQLAlchemy usage, especially the ORM, places a heavy stress on working within the context
+ of a transaction at all times; the "implicit execution" concept makes the job of
+ associating statement execution with a particular transaction much more difficult.
+ The :meth:`.Executable.execute` method on a particular SQL statement
+ usually implies that the execution is not part of any particular transaction, which is
+ usually not the desired effect.
+
In both "connectionless" examples, the
-:class:`~sqlalchemy.engine.base.Connection` is created behind the scenes; the
-:class:`~sqlalchemy.engine.base.ResultProxy` returned by the ``execute()``
-call references the :class:`~sqlalchemy.engine.base.Connection` used to issue
+:class:`~sqlalchemy.engine.Connection` is created behind the scenes; the
+:class:`~sqlalchemy.engine.ResultProxy` returned by the ``execute()``
+call references the :class:`~sqlalchemy.engine.Connection` used to issue
the SQL statement. When the :class:`.ResultProxy` is closed, the underlying
:class:`.Connection` is closed for us, resulting in the
DBAPI connection being returned to the pool with transactional resources removed.
+
.. _threadlocal_strategy:
Using the Threadlocal Execution Strategy
with the current thread, such that all parts of the
application can participate in that transaction implicitly without the need to
explicitly reference a :class:`.Connection`.
-"threadlocal" is designed for a very specific pattern of use, and is not
-appropriate unless this very specfic pattern, described below, is what's
-desired. It has **no impact** on the "thread safety" of SQLAlchemy components
-or one's application. It also should not be used when using an ORM
-:class:`~sqlalchemy.orm.session.Session` object, as the
-:class:`~sqlalchemy.orm.session.Session` itself represents an ongoing
-transaction and itself handles the job of maintaining connection and
-transactional resources.
+
+.. note::
+
+ The "threadlocal" feature is generally discouraged. It's
+ designed for a particular pattern of usage which is generally
+ considered as a legacy pattern. It has **no impact** on the "thread safety"
+ of SQLAlchemy components
+ or one's application. It also should not be used when using an ORM
+ :class:`~sqlalchemy.orm.session.Session` object, as the
+ :class:`~sqlalchemy.orm.session.Session` itself represents an ongoing
+ transaction and itself handles the job of maintaining connection and
+ transactional resources.
Enabling ``threadlocal`` is achieved as follows::
Binding MetaData to an Engine or Connection
--------------------------------------------
-Notice in the previous section the creator/dropper methods accept an argument
-for the database engine in use. When a schema construct is combined with an
-:class:`~sqlalchemy.engine.base.Engine` object, or an individual
-:class:`~sqlalchemy.engine.base.Connection` object, we call this the *bind*.
-In the above examples the bind is associated with the schema construct only
-for the duration of the operation. However, the option exists to persistently
-associate a bind with a set of schema constructs via the
-:class:`~sqlalchemy.schema.MetaData` object's ``bind`` attribute::
-
- engine = create_engine('sqlite://')
-
- # create MetaData
- meta = MetaData()
-
- # bind to an engine
- meta.bind = engine
-
-We can now call methods like :func:`~sqlalchemy.schema.MetaData.create_all`
-without needing to pass the :class:`~sqlalchemy.engine.base.Engine`::
-
- meta.create_all()
-
-The MetaData's bind is used for anything that requires an active connection,
-such as loading the definition of a table from the database automatically
-(called *reflection*)::
-
- # describe a table called 'users', query the database for its columns
- users_table = Table('users', meta, autoload=True)
-
-As well as for executing SQL constructs that are derived from that MetaData's table objects::
-
- # generate a SELECT statement and execute
- result = users_table.select().execute()
-
-Binding the MetaData to the Engine is a **completely optional** feature. The
-above operations can be achieved without the persistent bind using
-parameters::
-
- # describe a table called 'users', query the database for its columns
- users_table = Table('users', meta, autoload=True, autoload_with=engine)
-
- # generate a SELECT statement and execute
- result = engine.execute(users_table.select())
-
-Should you use bind ? It's probably best to start without it, and wait for a
-specific need to arise. Bind is useful if:
-
-* You aren't using the ORM, are usually using "connectionless" execution, and
- find yourself constantly needing to specify the same
- :class:`~sqlalchemy.engine.base.Engine` object throughout the entire
- application. Bind can be used here to provide "implicit" execution.
-* Your application has multiple schemas that correspond to different engines.
- Using one :class:`~sqlalchemy.schema.MetaData` for each schema, bound to
- each engine, provides a decent place to delineate between the schemas. The
- ORM will also integrate with this approach, where the :class:`.Session` will
- naturally use the engine that is bound to each table via its metadata
- (provided the :class:`.Session` itself has no ``bind`` configured.).
-
-Alternatively, the ``bind`` attribute of :class:`~sqlalchemy.schema.MetaData`
-is *confusing* if:
-
-* Your application talks to multiple database engines at different times,
- which use the *same* set of :class:`.Table` objects. It's usually confusing
- and unnecessary to begin to create "copies" of :class:`.Table` objects just
- so that different engines can be used for different operations. An example
- is an application that writes data to a "master" database while performing
- read-only operations from a "read slave". A global
- :class:`~sqlalchemy.schema.MetaData` object is *not* appropriate for
- per-request switching like this, although a
- :class:`~sqlalchemy.schema.ThreadLocalMetaData` object is.
-* You are using the ORM :class:`.Session` to handle which class/table is bound
- to which engine, or you are using the :class:`.Session` to manage switching
- between engines. Its a good idea to keep the "binding of tables to engines"
- in one place - either using :class:`~sqlalchemy.schema.MetaData` only (the
- :class:`.Session` can of course be present, it just has no ``bind``
- configured), or using :class:`.Session` only (the ``bind`` attribute of
- :class:`~sqlalchemy.schema.MetaData` is left empty).
+The :class:`.MetaData` object can be associated directly with an :class:`.Engine`
+or :class:`.Connection` so that SQL statement objects gain an :meth:`.Executable.execute`
+method, and also provide an alternate means to the ORM :class:`.Session` object
+in order to locate an :class:`.Engine`, given a particular mapping to execute a
+query against. However, this pattern is **not recommended for general use**.
+For background, see, :ref:`dbengine_implicit`.
Specifying the Schema Name
---------------------------
assumed that all subsequent argument dictionaries are compatible with that
statement.
-Connectionless / Implicit Execution
-====================================
-
-We're executing our :class:`~sqlalchemy.sql.expression.Insert` using a
-:class:`~sqlalchemy.engine.base.Connection`. There's two options that allow
-you to not have to deal with the connection part. You can execute in the
-**connectionless** style, using the engine, which checks out from the
-connection pool a connection for you, performs the execute operation with that
-connection, and then checks the connection back into the pool upon completion
-of the operation:
-
-.. sourcecode:: pycon+sql
-
- {sql}>>> result = engine.execute(users.insert(), name='fred', fullname="Fred Flintstone")
- INSERT INTO users (name, fullname) VALUES (?, ?)
- ('fred', 'Fred Flintstone')
- COMMIT
-
-and you can save even more steps than that, if you connect the
-:class:`~sqlalchemy.engine.base.Engine` to the
-:class:`~sqlalchemy.schema.MetaData` object we created earlier. When this is
-done, all SQL expressions which involve tables within the
-:class:`~sqlalchemy.schema.MetaData` object will be automatically **bound** to
-the :class:`~sqlalchemy.engine.base.Engine`. In this case, we call it
-**implicit execution**:
-
-.. sourcecode:: pycon+sql
-
- >>> metadata.bind = engine
- {sql}>>> result = users.insert().execute(name="mary", fullname="Mary Contrary")
- INSERT INTO users (name, fullname) VALUES (?, ?)
- ('mary', 'Mary Contrary')
- COMMIT
-
-When the :class:`~sqlalchemy.schema.MetaData` is bound, statements will also
-compile against the engine's dialect. Since a lot of the examples here assume
-the default dialect, we'll detach the engine from the metadata which we just
-attached:
-
-.. sourcecode:: pycon+sql
-
- >>> metadata.bind = None
-
-Detailed examples of connectionless and implicit execution are available in
-the "Engines" chapter: :ref:`dbengine_implicit`.
-
.. _coretutorial_selecting:
Selecting