[Sqlalchemy-commits] [1372] sqlalchemy/branches/schema/doc/build/content/unitofwork.txt: basic idea
Brought to you by:
zzzeek
From: <co...@sq...> - 2006-05-02 00:18:43
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><style type="text/css"><!-- #msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; } #msg dt { float: left; width: 6em; font-weight: bold; } #msg dt:after { content:':';} #msg dl, #msg dt, #msg ul, #msg li { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; } #msg dl a { font-weight: bold} #msg dl a:link { color:#fc3; } #msg dl a:active { color:#ff0; } #msg dl a:visited { color:#cc6; } h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; } #msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; } #msg ul, pre { overflow: auto; } #patch { width: 100%; } #patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;} #patch .propset h4, #patch .binary h4 {margin:0;} #patch pre {padding:0;line-height:1.2em;margin:0;} #patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;} #patch .propset .diff, #patch .binary .diff {padding:10px 0;} #patch span {display:block;padding:0 10px;} #patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;} #patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;} #patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;} #patch .lines, .info {color:#888;background:#fff;} --></style> <title>[1372] sqlalchemy/branches/schema/doc/build/content/unitofwork.txt: basic idea is completed....pending edits</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1372</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-05-01 19:18:31 -0500 (Mon, 01 May 2006)</dd> </dl> <h3>Log Message</h3> <pre>basic idea is completed....pending edits</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemybranchesschemadocbuildcontentunitofworktxt">sqlalchemy/branches/schema/doc/build/content/unitofwork.txt</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemybranchesschemadocbuildcontentunitofworktxt"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/schema/doc/build/content/unitofwork.txt (1371 => 1372)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/schema/doc/build/content/unitofwork.txt 2006-05-01 23:56:37 UTC (rev 1371) +++ sqlalchemy/branches/schema/doc/build/content/unitofwork.txt 2006-05-02 00:18:31 UTC (rev 1372) </span><span class="lines">@@ -19,13 +19,13 @@ </span><span class="cx"> </span><span class="cx"> When dealing with mapped instances with regards to Sessions, an instance may be *attached* or *unattached* to a particular Session. An instance also may or may not correspond to an actual row in the database. The product of these two binary conditions yields us four general states a particular instance can have within the perspective of the Session: </span><span class="cx"> </span><del>-* Transient - a transient instance exists within memory only and is not associated with any Session. It also has no database identity and does not have a corresponding record in the database. When a new instance of a class is constructed, and no default session context exists with which to automatically attach the new instance, it is a transient instance. The instance can then be saved to a particular session in which case it becomes a *pending* instance. If a default session context exists, new instances are added to that Session by default and therefore become *pending* instances immediately. </del><ins>+* *Transient* - a transient instance exists within memory only and is not associated with any Session. It also has no database identity and does not have a corresponding record in the database. When a new instance of a class is constructed, and no default session context exists with which to automatically attach the new instance, it is a transient instance. The instance can then be saved to a particular session in which case it becomes a *pending* instance. If a default session context exists, new instances are added to that Session by default and therefore become *pending* instances immediately. </ins><span class="cx"> </span><del>-* Pending - a pending instance is a Session-attached object that has not yet been assigned a database identity. When the Session is flushed (i.e. changes are persisted to the database), a pending instance becomes persistent. </del><ins>+* *Pending* - a pending instance is a Session-attached object that has not yet been assigned a database identity. When the Session is flushed (i.e. changes are persisted to the database), a pending instance becomes persistent. </ins><span class="cx"> </span><del>-* Persistent - a persistent instance has a database identity and a corresponding record in the database, and is also associated with a particular Session. By "database identity" we mean the object is associated with a table or relational concept in the database combined with a particular primary key in that table. Objects that are loaded by SQLAlchemy in the context of a particular session are automatically considered persistent, as are formerly pending instances which have been subject to a session `flush()`. </del><ins>+* *Persistent* - a persistent instance has a database identity and a corresponding record in the database, and is also associated with a particular Session. By "database identity" we mean the object is associated with a table or relational concept in the database combined with a particular primary key in that table. Objects that are loaded by SQLAlchemy in the context of a particular session are automatically considered persistent, as are formerly pending instances which have been subject to a session `flush()`. </ins><span class="cx"> </span><del>-* Detached - a detached instance is an instance which has a database identity and corresponding row in the database, but is not attached to any Session. This occurs when an instance has been removed from a Session, either because the session itself was cleared or closed, or the instance was explicitly removed from the Session. The object can be re-attached with a session again in which case it becomes Persistent again. Detached instances are useful when an application needs to represent a long-running operation across multiple Sessions, needs to store an object in a serialized state and then restore it later (such as within an HTTP "session" object), or in some cases where code needs to load instances locally which will later be associated with some other Session. </del><ins>+* *Detached* - a detached instance is an instance which has a database identity and corresponding row in the database, but is not attached to any Session. This occurs when an instance has been removed from a Session, either because the session itself was cleared or closed, or the instance was explicitly removed from the Session. The object can be re-attached with a session again in which case it becomes Persistent again. Detached instances are useful when an application needs to represent a long-running operation across multiple Sessions, needs to store an object in a serialized state and then restore it later (such as within an HTTP "session" object), or in some cases where code needs to load instances locally which will later be associated with some other Session. </ins><span class="cx"> </span><span class="cx"> ### Acquiring a Session {@name=getting} </span><span class="cx"> </span><span class="lines">@@ -51,7 +51,7 @@ </span><span class="cx"> session = create_session(bind_to=conn) </span><span class="cx"> </span><span class="cx"> </span><del>-The session to which an object is attached can be acquired via the `object_session()` method, which returns the appropriate `Session` if the object is pending or persistent, or `None` if the object is transient or detached: </del><ins>+The session to which an object is attached can be acquired via the `object_session()` function, which returns the appropriate `Session` if the object is pending or persistent, or `None` if the object is transient or detached: </ins><span class="cx"> </span><span class="cx"> {python} </span><span class="cx"> session = object_session(obj) </span><span class="lines">@@ -238,7 +238,7 @@ </span><span class="cx"> </span><span class="cx"> Use `expunge` when youd like to remove an object altogether from memory, such as before calling `del` on it, which will prevent any "ghost" operations occuring when the session is flushed. </span><span class="cx"> </span><del>-#### bind_mapper()/bind_table() {@name=bind} </del><ins>+#### bind\_mapper() / bind\_table() {@name=bind} </ins><span class="cx"> </span><span class="cx"> Both of these methods receive two arguments; in the case of `bind_mapper()`, it is a `Mapper` and an `Engine` or `Connection` instance; in the case of `bind_table()`, it is a `Table` instance or other `Selectable` (such as an `Alias`, `Select`, etc.), and an `Engine` or `Connection` instance. </span><span class="cx"> </span><span class="lines">@@ -254,7 +254,7 @@ </span><span class="cx"> </span><span class="cx"> The `save_or_update()` method is a convenience method which will call the `save()` or `update()` methods appropriately dependening on whether or not the instance has a database identity (but the instance still must be unattached). </span><span class="cx"> </span><del>-#### save_or_update() {@name=save_or_update} </del><ins>+#### save\_or\_update() {@name=saveorupdate} </ins><span class="cx"> </span><span class="cx"> This method is a combination of the `save()` and `update()` methods, which will examine the given instance for a database identity (i.e. if it is transient or detached), and will call the implementation of `save()` or `update()` as appropriate. Use `save_or_update()` to add unattached instances to a session when you're not sure if they were newly created or not. </span><span class="cx"> </span><span class="lines">@@ -296,6 +296,8 @@ </span><span class="cx"> </span><span class="cx"> Note that cascading doesn't do anything that isn't possible by manually calling Session methods on individual instances within a hierarchy, it merely automates common operations on a group of associated instances. </span><span class="cx"> </span><ins>+The default value for `cascade` on `relation()`s is `save-update`, and the `private=True` keyword argument is a synonym for `cascade="all, delete-orphan"`. + </ins><span class="cx"> ### SessionTransaction {@name=transaction} </span><span class="cx"> </span><span class="cx"> SessionTransaction is a multi-engine transaction manager, which aggregates one or more Engine/Connection pairs and keeps track of a Transaction object for each one. As the Session receives requests to execute SQL statements, it uses the Connection that is referenced by the SessionTransaction. At commit time, the underyling Session is flushed, and each Transaction is the committed. </span><span class="lines">@@ -319,15 +321,15 @@ </span><span class="cx"> </span><span class="cx"> `SessionTransaction`, like the `Transaction` off of `Connection` also supports "nested" behavior, and is safe to pass to other functions which then issue their own `begin()`/`commit()` pair; only the outermost `begin()`/`commit()` pair actually affects the transaction, and any call to `rollback()` within a particular call stack will issue a rollback. </span><span class="cx"> </span><del>-#### Analyzing Object Commits {@name=logging} </del><ins>+### Analyzing Object Flushes {@name=logging} </ins><span class="cx"> </span><del>-The objectstore module can log an extensive display of its "commit plans", which is a graph of its internal representation of objects before they are committed to the database. To turn this logging on: </del><ins>+The session module can log an extensive display of its "flush plans", which is a graph of its internal representation of objects before they are written to the database. To turn this logging on: </ins><span class="cx"> </span><span class="cx"> {python} </span><span class="cx"> # make an engine with echo_uow </span><span class="cx"> engine = create_engine('myengine...', echo_uow=True) </span><span class="cx"> </span><del>-Commits will then dump to the standard output displays like the following: </del><ins>+The `flush()` operation will then dump to the standard output displays like the following: </ins><span class="cx"> </span><span class="cx"> {code} </span><span class="cx"> Task dump: </span><span class="lines">@@ -355,4 +357,8 @@ </span><span class="cx"> |---- </span><span class="cx"> </span><span class="cx"> The above graph can be read straight downwards to determine the order of operations. It indicates "save User 6016624, process each element in the 'addresses' list on User 6016624, save Address 6034384, Address 6034256". </span><ins>+ +Of course, one can also get a good idea of the order of operations just by logging the actual SQL statements executed. + +The format of the above display is definitely a work in progress and amazingly, is far simpler to read than it was in earlier releases. It will hopefully be further refined in future releases to be more intuitive (while not losing any information). </ins><span class="cx"> </span></span></pre> </div> </div> </body> </html> |