From: Mike Bayer Date: Wed, 8 Aug 2012 00:07:58 +0000 (-0400) Subject: - modernize some merge docs a bit X-Git-Tag: rel_0_7_9~59 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b8883b771b4c6932506571ccc8968665cbe1d44f;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - modernize some merge docs a bit --- diff --git a/doc/build/orm/session.rst b/doc/build/orm/session.rst index 4c376b47bb..aeddec0664 100644 --- a/doc/build/orm/session.rst +++ b/doc/build/orm/session.rst @@ -420,10 +420,32 @@ taking the state of any kind of object structure without regard for its origins or current session associations and placing that state within a session. Here's two examples: +* An application wants to transfer the state of a series of objects + into a :class:`.Session` maintained by a worker thread or other + concurrent system. :meth:`~.Session.merge` makes a copy of each object + to be placed into this new :class:`.Session`. At the end of the operation, + the parent thread/process maintains the objects it started with, + and the thread/worker can proceed with local copies of those objects. + +* An application is storing objects in an in-memory cache, shared by + many :class:`.Session` objects simultaneously. :meth:`~.Session.merge` + is used each time an object is retrieved from the cache to create + a local copy of it in each :class:`.Session` which requests it. + The cached object remains detached; only its state is moved into + copies of itself that are local to individual :class:`~.Session` + objects. + + In the caching use case, it's common that the ``load=False`` flag + is used to remove the overhead of reconciling the object's state + with the database. There's also a "bulk" version of + :meth:`~.Session.merge` called :meth:`~.Query.merge_result` + that was designed to work with cache-extended :class:`.Query` + objects - see the section :ref:`examples_caching`. + * An application which reads an object structure from a file and wishes to save it to the database might parse the file, build up the structure, and then use - :func:`~sqlalchemy.orm.session.Session.merge` to save it + :meth:`~.Session.merge` to save it to the database, ensuring that the data within the file is used to formulate the primary key of each element of the structure. Later, when the file has changed, the same @@ -432,25 +454,7 @@ session. Here's two examples: and the :class:`~sqlalchemy.orm.session.Session` will automatically update the database to reflect those changes. -* A web application stores mapped entities within an HTTP session object. - When each request starts up, the serialized data can be - merged into the session, so that the original entity may - be safely shared among requests and threads. - -:func:`~sqlalchemy.orm.session.Session.merge` is frequently used by -applications which implement their own second level caches. This refers to an -application which uses an in memory dictionary, or an tool like Memcached to -store objects over long running spans of time. When such an object needs to -exist within a :class:`~sqlalchemy.orm.session.Session`, -:func:`~sqlalchemy.orm.session.Session.merge` is a good choice since it leaves -the original cached object untouched. For this use case, merge provides a -keyword option called ``load=False``. When this boolean flag is set to -``False``, :func:`~sqlalchemy.orm.session.Session.merge` will not issue any -SQL to reconcile the given object against the current state of the database, -thereby reducing query overhead. The limitation is that the given object and -all of its children may not contain any pending changes, and it's also of -course possible that newer information in the database will not be present on -the merged object, since no load is issued. + Merge Tips ~~~~~~~~~~ diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index 03af876538..52b4f0d9a1 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -1318,6 +1318,29 @@ class Session(object): See :ref:`unitofwork_merging` for a detailed discussion of merging. + :param instance: Instance to be merged. + :param load: Boolean, when False, :meth:`.merge` switches into + a "high performance" mode which causes it to skip all database + access. The state of the given object is transferred directly + into the :class:`.Session` without checking the database + for existing data or discrepancies. This flag is used for + cases such as transferring graphs of objects into a :class:`.Session` + from a second level cache, or to transfer just-loaded objects + into the :class:`.Session` owned by a worker thread or process + without re-querying the database. + + The ``load=False`` use case adds the caveat that the given + object has to be in a "clean" state. This is so that when + the merge operation cascades onto related objects and + collections, the related values can be "stamped" onto the + target object as is, without concern for reconciling their + contents with any existing database value. While there's no technical + reason the state of the object can't be taken as is whether or + not it's dirty, it suggests a mis-use of the method, as state which + wasn't pulled from the database originally can't reliably be passed back to + the database without knowing the database's current state. + + """ if 'dont_load' in kw: load = not kw['dont_load']