]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- document query.get(), ObjectDeletedError fully, [ticket:2146]
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 23 Jul 2011 16:27:09 +0000 (12:27 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 23 Jul 2011 16:27:09 +0000 (12:27 -0400)
doc/build/orm/loading.rst
doc/build/orm/tutorial.rst
lib/sqlalchemy/orm/exc.py
lib/sqlalchemy/orm/query.py

index 3b3d1ff0751d1786492f5a261574b346c1234ca8..45b94191f70d4a4967f8a9fb179733d55ec28cf8 100644 (file)
@@ -330,7 +330,7 @@ references a scalar many-to-one reference.
  * When using the default lazy loading, a load of 100 objects will like in the case of the collection
    emit as many as 101 SQL statements.  However - there is a significant exception to this, in that
    if the many-to-one reference is a simple foreign key reference to the target's primary key, each
-   reference will be checked first in the current identity map using ``query.get()``.  So here, 
+   reference will be checked first in the current identity map using :meth:`.Query.get`.  So here, 
    if the collection of objects references a relatively small set of target objects, or the full set
    of possible target objects have already been loaded into the session and are strongly referenced,
    using the default of `lazy='select'` is by far the most efficient way to go.
index 410e1a0692ed6a3b1004bbe59e3fd7cb198c3d0b..af44e4da83fbb2293bf57a83195b10dbba16c933 100644 (file)
@@ -1491,7 +1491,7 @@ their parent:
     >>> mapper(Address, addresses_table) # doctest: +ELLIPSIS
     <Mapper at 0x...; Address>
 
-Now when we load Jack (below using :meth:`~Query.get`, which loads by primary key),
+Now when we load Jack (below using :meth:`~.Query.get`, which loads by primary key),
 removing an address from his ``addresses`` collection will result in that
 ``Address`` being deleted:
 
index 3bfb2708cd637034fc90b456f802fa698f251902..1812f0d7209a285e14cd71fefaddffb4beaf01f6 100644 (file)
@@ -77,7 +77,24 @@ class UnmappedClassError(UnmappedError):
 
 
 class ObjectDeletedError(sa.exc.InvalidRequestError):
-    """An refresh() operation failed to re-retrieve an object's row."""
+    """A refresh operation failed to retrieve the database
+    row corresponding to an object's known primary key identity.
+    
+    A refresh operation proceeds when an expired attribute is 
+    accessed on an object, or when :meth:`.Query.get` is
+    used to retrieve an object which is, upon retrieval, detected
+    as expired.   A SELECT is emitted for the target row
+    based on primary key; if no row is returned, this
+    exception is raised.
+    
+    The true meaning of this exception is simply that 
+    no row exists for the primary key identifier associated
+    with a persistent object.   The row may have been 
+    deleted, or in some cases the primary key updated
+    to a new value, outside of the ORM's management of the target
+    object.   
+    
+    """
 
 
 class UnmappedColumnError(sa.exc.InvalidRequestError):
index 701b376af90779193b557f182568735d558986bd..8d64d69b4111c63de9db233f522af3926f623140 100644 (file)
@@ -635,22 +635,61 @@ class Query(object):
         self._execution_options['stream_results'] = True
 
     def get(self, ident):
-        """Return an instance of the object based on the 
-        given identifier, or ``None`` if not found.
-
-        The ``ident`` argument is a scalar or tuple of 
-        primary key column values
-        in the order of the mapper's "primary key" setting, which
-        defaults to the list of primary key columns for the 
-        mapped :class:`.Table`.
+        """Return an instance based on the given primary key identifier, 
+        or ``None`` if not found.
+        
+        E.g.::
+        
+            my_user = session.query(User).get(5)
+            
+            some_object = session.query(VersionedFoo).get((5, 10))
+        
+        :meth:`~.Query.get` is special in that it provides direct 
+        access to the identity map of the owning :class:`.Session`.
+        If the given primary key identifier is present
+        in the local identity map, the object is returned
+        directly from this collection and no SQL is emitted, 
+        unless the object has been marked fully expired.
+        If not present,
+        a SELECT is performed in order to locate the object.
+        
+        :meth:`~.Query.get` also will perform a check if 
+        the object is present in the identity map and 
+        marked as expired - a SELECT 
+        is emitted to refresh the object as well as to
+        ensure that the row is still present.
+        If not, :class:`~sqlalchemy.orm.exc.ObjectDeletedError` is raised.
+        
+        :meth:`~.Query.get` is only used to return a single
+        mapped instance, not multiple instances or 
+        individual column constructs, and strictly
+        on a single primary key value.  The originating
+        :class:`.Query` must be constructed in this way,
+        i.e. against a single mapped entity,
+        with no additional filtering criterion.  Loading
+        options via :meth:`~.Query.options` may be applied
+        however, and will be used if the object is not
+        yet locally present.
+        
+        A lazy-loading, many-to-one attribute configured
+        by :func:`.relationship`, using a simple
+        foreign-key-to-primary-key criterion, will also use an 
+        operation equivalent to :meth:`~.Query.get` in order to retrieve
+        the target value from the local identity map
+        before querying the database.  See :ref:`loading_toplevel`
+        for further details on relationship loading.
+        
+        :param ident: A scalar or tuple value representing
+         the primary key.   For a composite primary key,
+         the order of identifiers corresponds in most cases
+         to that of the mapped :class:`.Table` object's 
+         primary key columns.  For a :func:`.mapper` that
+         was given the ``primary key`` argument during
+         construction, the order of identifiers corresponds 
+         to the elements present in this collection.
+
+        :return: The object instance, or ``None``.
         
-        :meth:`get` returns only a single mapped instance, or
-        ``None``.  It is not intended to return rows or scalar
-        column values, therefore the :class:`.Query` must be 
-        constructed only against a single mapper or mapped class,
-        not a SQL expression or multiple entities.
-        Other usages raise an error.
-
         """
 
         # convert composite types to individual args