summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2007-08-09 17:35:00 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2007-08-09 17:35:00 +0000
commit7c9d8d81aee73444f0ec17c4a24c616c133bd573 (patch)
tree4f7e836ceff767effce7e394a68bee5a12f77488 /lib/sqlalchemy
parent45dd4437326f86b3b9106f4c5d0c5ce1511cbf90 (diff)
downloadsqlalchemy-7c9d8d81aee73444f0ec17c4a24c616c133bd573.tar.gz
session docs, CHANGES updates
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/orm/__init__.py3
-rw-r--r--lib/sqlalchemy/orm/session.py150
2 files changed, 147 insertions, 6 deletions
diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py
index f6542329c..fb9e812e1 100644
--- a/lib/sqlalchemy/orm/__init__.py
+++ b/lib/sqlalchemy/orm/__init__.py
@@ -34,6 +34,9 @@ __all__ = [ 'relation', 'column_property', 'composite', 'backref', 'eagerload',
def scoped_session(session_factory, scopefunc=None):
"""Provides thread-local management of Sessions.
+
+ This is a front-end function to the [sqlalchemy.orm.scoping#ScopedSession]
+ class.
Usage::
diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py
index e61edb8a0..e7268dd98 100644
--- a/lib/sqlalchemy/orm/session.py
+++ b/lib/sqlalchemy/orm/session.py
@@ -15,7 +15,47 @@ from sqlalchemy.orm.mapper import global_extensions
__all__ = ['Session', 'SessionTransaction']
def sessionmaker(bind=None, class_=None, autoflush=True, transactional=True, **kwargs):
- """Generate a Session configuration."""
+ """Generate a custom-configured [sqlalchemy.orm.session#Session] class.
+
+ The returned object is a subclass of ``Session``, which, when instantiated with no
+ arguments, uses the
+ keyword arguments configured here as its constructor arguments. It is intended
+ that the `sessionmaker()` function be called within the global scope of an application,
+ and the returned class be made available to the rest of the application as the
+ single class used to instantiate sessions.
+
+ e.g.::
+
+ # global scope
+ Session = sessionmaker(autoflush=False)
+
+ # later, in a local scope, create and use a session:
+ sess = Session()
+
+ Any keyword arguments sent to the constructor itself will override the "configured"
+ keywords::
+
+ Session = sessionmaker()
+
+ # bind an individual session to a connection
+ sess = Session(bind=connection)
+
+ The class also includes a special classmethod ``configure()``, which allows
+ additional configurational options to take place after the custom ``Session``
+ class has been generated. This is useful particularly for defining the
+ specific ``Engine`` (or engines) to which new instances of ``Session``
+ should be bound::
+
+ Session = sessionmaker()
+ Session.configure(bind=create_engine('sqlite:///foo.db'))
+
+ sess = Session()
+
+ The function features a single keyword argument of its own, `class_`, which
+ may be used to specify an alternate class other than ``sqlalchemy.orm.session.Session``
+ which should be used by the returned class. All other keyword arguments sent to
+ `sessionmaker()` are passed through to the instantiated `Session()` object.
+ """
kwargs['bind'] = bind
kwargs['autoflush'] = autoflush
@@ -46,11 +86,14 @@ def sessionmaker(bind=None, class_=None, autoflush=True, transactional=True, **k
class SessionTransaction(object):
"""Represents a Session-level Transaction.
- This corresponds to one or more sqlalchemy.engine.Transaction
- instances behind the scenes, with one Transaction per Engine in
+ This corresponds to one or more [sqlalchemy.engine_Transaction]
+ instances behind the scenes, with one ``Transaction`` per ``Engine`` in
use.
- The SessionTransaction object is **not** threadsafe.
+ Typically, usage of ``SessionTransaction`` is not necessary; use
+ the ``begin()`` and ``commit()`` methods on ``Session`` itself.
+
+ The ``SessionTransaction`` object is **not** threadsafe.
"""
def __init__(self, session, parent=None, autoflush=True, nested=False):
@@ -220,6 +263,71 @@ class Session(object):
"""
def __init__(self, bind=None, autoflush=True, transactional=False, twophase=False, echo_uow=False, weak_identity_map=False, binds=None):
+ """Construct a new Session.
+
+ autoflush
+ when ``True``, all query operations will issue a ``flush()`` call to this
+ ``Session`` before proceeding. This is a convenience feature so that
+ ``flush()`` need not be called repeatedly in order for database queries to
+ retrieve results. It's typical that ``autoflush`` is used in conjunction with
+ ``transactional=True``, so that ``flush()`` is never called; you just call
+ ``commit()`` when changes are complete to finalize all changes to the
+ database.
+
+ bind
+ an optional ``Engine`` or ``Connection`` to which this ``Session`` should be
+ bound. When specified, all SQL operations performed by this session will
+ execute via this connectable.
+
+ binds
+ an optional dictionary, which contains more granular "bind" information than
+ the ``bind`` parameter provides. This dictionary can map individual ``Table``
+ instances as well as ``Mapper`` instances to individual ``Engine`` or
+ ``Connection`` objects. Operations which proceed relative to a particular
+ ``Mapper`` will consult this dictionary for the direct ``Mapper`` instance as
+ well as the mapper's ``mapped_table`` attribute in order to locate an
+ connectable to use. The full resolution is described in the ``get_bind()``
+ method of ``Session``. Usage looks like::
+
+ sess = Session(binds={
+ SomeMappedClass : create_engine('postgres://engine1'),
+ somemapper : create_engine('postgres://engine2'),
+ some_table : create_engine('postgres://engine3'),
+ })
+
+ Also see the ``bind_mapper()`` and ``bind_table()`` methods.
+
+ echo_uow
+ When ``True``, configure Python logging to dump all unit-of-work
+ transactions. This is the equivalent of
+ ``logging.getLogger('sqlalchemy.orm.unitofwork').setLevel(logging.DEBUG)``.
+
+ transactional
+ Set up this ``Session`` to automatically begin transactions. Setting this
+ flag to ``True`` is the rough equivalent of calling ``begin()`` after each
+ ``commit()`` operation, after each ``rollback()``, and after each
+ ``close()``. Basically, this has the effect that all session operations are
+ performed within the context of a transaction. Note that the ``begin()``
+ operation does not immediately utilize any connection resources; only when
+ connection resources are first required do they get allocated into a
+ transactional context.
+
+ twophase
+ when ``True``, all transactions will be started using
+ [sqlalchemy.engine_TwoPhaseTransaction]. During a ``commit()``, after
+ ``flush()`` has been issued for all attached databaes, the ``prepare()``
+ method on each database's ``TwoPhaseTransaction`` will be called. This allows
+ each database to roll back the entire transaction, before each transaction is
+ committed.
+
+ weak_identity_map
+ when ``True``, use a ``WeakValueDictionary`` instead of a regular ``dict``
+ for this ``Session`` object's identity map. This will allow objects which
+ fall out of scope to be automatically removed from the ``Session``. However,
+ objects who have been marked as "dirty" will also be garbage collected, and
+ those changes will not be persisted.
+
+ """
self.uow = unitofwork.UnitOfWork(weak_identity_map=weak_identity_map)
self.bind = bind
@@ -263,9 +371,20 @@ class Session(object):
create_transaction = begin
def begin_nested(self):
+ """begin a 'nested' transaction on this Session.
+
+ this utilizes a SAVEPOINT transaction for databases
+ which support this feature.
+ """
return self.begin(nested=True)
def rollback(self):
+ """rollback the current transaction in progress.
+
+ If no transaction is in progress, this method is a
+ pass-thru.
+ """
+
if self.transaction is None:
pass
else:
@@ -279,6 +398,19 @@ class Session(object):
self.begin()
def commit(self):
+ """commit the current transaction in progress.
+
+ If no transaction is in progress, this method raises
+ an InvalidRequestError.
+
+ If the ``begin()`` method was called on this ``Session``
+ additional times subsequent to its first call,
+ ``commit()`` will not actually commit, and instead
+ pops an internal SessionTransaction off its internal stack
+ of transactions. Only when the "root" SessionTransaction
+ is reached does an actual database-level commit occur.
+
+ """
if self.transaction is None:
if self.transactional:
self.begin()
@@ -305,7 +437,8 @@ class Session(object):
progress.
the "mapper" argument is a class or mapper to which a bound engine
- will be located; use this when the Session itself is unbound.
+ will be located; use this when the Session itself is either bound
+ to multiple engines or connections, or is not bound to any connectable.
"""
if self.transaction is not None:
@@ -322,7 +455,7 @@ class Session(object):
If this method allocates a new ``Connection`` for the operation,
then the ``ResultProxy`` 's ``close()`` method will release the
- resources of the underlying ``Connection``, otherwise its a no-op.
+ resources of the underlying ``Connection``.
"""
return self.connection(mapper, close_with_result=True).execute(clause, params or {}, **kwargs)
@@ -335,6 +468,11 @@ class Session(object):
"""Close this Session.
This clears all items and ends any transaction in progress.
+
+ If this session were created with ``transactional=True``, a
+ new transaction is immediately begun. Note that this new
+ transaction does not use any connection resources until they
+ are first needed.
"""
self.clear()