Mike Bayer avatar Mike Bayer committed 2c9b3c9

updates

Comments (0)

Files changed (3)

doc/build/orm/session.rst

 want to work with them again, so that they can resume their normal task of
 representing database state.
 
+.. _session_getting:
+
 Getting a Session
 =================
 
     example's sake!  In reality, the :class:`.sessionmaker` would be somewhere
     at the module level.   The calls to instantiate :class:`.Session`
     would then be placed at the point in the application where database
-    conversations begin (see :ref:`session_faq_whentocreate`).
+    conversations begin.
 
 * When do I construct a :class:`.Session`, when do I commit it, and when do I close it ?
 
     begin a new transaction if it is used again, subsequent to the previous
     transaction ending; from this it follows that the :class:`.Session`
     is capable of having a lifespan across many transactions, though only
-    one at a time.   We refer to these two concepts as *transaction scope*
-    and *session scope*.
+    one at a time.   We refer to these two concepts as **transaction scope**
+    and **session scope**.
 
     The implication here is that the SQLAlchemy ORM is encouraging the
     developer to establish these two scopes in his or her application,
     pattern which establishes one as soon as it is needed.  The request
     then proceeds, with some system in place where application logic can access
     the current :class:`.Session` in a manner associated with how the actual
-    requset object is accessed.  As the request ends, the :class:`.Session`
+    request object is accessed.  As the request ends, the :class:`.Session`
     is torn down as well, usually through the usage of event hooks provided
     by the web framework.   The transaction used by the :class:`.Session`
     may also be committed at this point, or alternatively the application may
 
     In those situations where integration libraries are not available,
     SQLAlchemy includes its own "helper" class known as
-    :class:`.scoped_session`.  This object actually is used as the basis
-    of some integration packages, and provides both a quick way
+    :class:`.scoped_session`.   A tutorial on the usage of this object
+    is at :ref:`unitofwork_contextual`.   It provides both a quick way
     to associate a :class:`.Session` with the current thread, as well as
     patterns to associate :class:`.Session` objects with other kinds of
     scopes.
     a series of operations for some period of time, which can be committed
     at the end.   Some examples:
 
-    * A background daemon which spawns off child forks for example
+    * A background daemon which spawns off child forks
       would want to create a :class:`.Session` local to each child
       process work with that :class:`.Session` through the life of the "job"
       that the fork is handling, then tear it down when the job is completed.
 :class:`.Session` with a thread implies it is also associated with the web request
 running within that thread, and vice versa, provided that the :class:`.Session` is
 created only after the web request begins and torn down just before the web request ends.
-So it is a very common practice to use :class:`.scoped_session` as a quick way
+So it is a common practice to use :class:`.scoped_session` as a quick way
 to integrate the :class:`.Session` with a web application.  The sequence
 diagram below illustrates this flow::
 
 based on any existing system of getting at "the current thing we are working with".
 
 Suppose a web framework defines a library function ``get_current_request()``.  An application
-build on this framework can call this function at any time, and the result will be
+built using this framework can call this function at any time, and the result will be
 some kind of ``Request`` object that represents the current request being processed.
 If the ``Request`` object is hashable, then this function can be easily integrated with
 :class:`.scoped_session` to associate the :class:`.Session` with the request.  Below we illustrate

lib/sqlalchemy/orm/scoping.py

         else:
             self.registry = ThreadLocalRegistry(session_factory)
 
-    def __call__(self, **kwargs):
-        """Return the current :class:`.Session`."""
-        if kwargs:
-            scope = kwargs.pop('scope', False)
+    def __call__(self, **kw):
+        """Return the current :class:`.Session`, creating it
+        using the session factory if not present.
+
+        :param \**kw: Keyword arguments will be passed to the
+         session factory callable, if an existing :class:`.Session`
+         is not present.  If the :class:`.Session` is present and
+         keyword arguments have been passed, :class:`.InvalidRequestError`
+         is raised.
+
+        """
+        if kw:
+            scope = kw.pop('scope', False)
             if scope is not None:
                 if self.registry.has():
                     raise sa_exc.InvalidRequestError(
                             "Scoped session is already present; "
                             "no new arguments may be specified.")
                 else:
-                    sess = self.session_factory(**kwargs)
+                    sess = self.session_factory(**kw)
                     self.registry.set(sess)
                     return sess
             else:
-                return self.session_factory(**kwargs)
+                return self.session_factory(**kw)
         else:
             return self.registry()
 
     def remove(self):
-        """Dispose of the current contextual session."""
+        """Dispose of the current :class:`.Session`, if present.
+
+        This will first call :meth:`.Session.close` method
+        on the current :class:`.Session`, which releases any existing
+        transactional/connection resources still being held; transactions
+        specifically are rolled back.  The :class:`.Session` is then
+        discarded.   Upon next usage within the same scope,
+        the :class:`.scoped_session` will produce a new
+        :class:`.Session` object.
+
+        """
 
         if self.registry.has():
             self.registry().close()

lib/sqlalchemy/orm/session.py

     with an existing :class:`.sessionmaker` factory before it is first
     used::
 
+        # application starts
         Session = sessionmaker()
-        Session.configure(bind=create_engine('sqlite:///foo.db'))
+
+        # ... later
+        engine = create_engine('sqlite:///foo.db')
+        Session.configure(bind=engine)
 
         sess = Session()
 
+    .. seealso:
+
+        :ref:`session_getting` - introductory text on creating
+        sessions using :class:`.sessionmaker`.
+
     """
 
     def __init__(self, bind=None, class_=Session, autoflush=True,
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.