Re: [sqlalchemy] Session: close(), remove(), expire_all() and expunge_all()

2011-03-19 Thread Israel Ben Guilherme Fonseca
Thank you very much for the answers.

No doubts for now.

2011/3/18 Michael Bayer mike...@zzzcomputing.com


 On Mar 18, 2011, at 2:55 PM, Israel Ben Guilherme Fonseca wrote:

  Hi everybody,
 
  I'm new with SQLAlchemy and I'm trying to understand better the Session
 object.
 
  First of all, why the expire_all() exists?

 The purpose is to remove any database-loaded state from all current objects
 so that the next access of any attribute, or any query execution, will
 retrieve new state, freshening those objects which are still referenced
 outside of the session with the most recent available state.   It is called
 automatically upon commit() or rollback() assuming an autocommit=False
 session, so that when the transaction, and its isolated environment, come to
 an end, subsequent accesses of those objects will acquire new data from
 whatever other transactions were committed subsequent to the previous
 transaction.   expire_all() itself is useful when:

 - the session is used in autocommit=True mode, and new changes from other
 transactions are desired.
 - against a database that does not support transactions, or perhaps within
 a weakly isolated transaction, again to load changes from other transactions
 or connections.
 - when SQL statements have been executed against the current transaction
 using execute() which may have changed significant portions of loaded state
 on the database.


  Shouldn't it be always better to expunge_all() instead? If it is expired,
 at the use of the instance another query would be issued to reattach it
 anyway, so why keep useless instances in the identity map (maybe i'm wrong
 about this fact, i dont know exactly how the identity map works).

 They're not useless at all if you are performing operations upon them which
 span the scope of multiple transactions, or have any of the above use cases,
 and don't wish to re-establish a full graph of objects in memory.
 In-memory objects are essentially proxy objects to an underlying database
 transaction.  The Session mediates this relationship.


 
  Second, when we should call the close() method?

 when you wish to release the transactional and connection pool resources of
 the Session and remove all objects.


  I dont think if i get it at all. Let's say that I have the following DAO:
 
  PersonDAO:
  def insert(self, person):
   session = Session()
   session.add(person)
   session.commit() // why the commit starts a new transaction?
 should'n it only start again the next database access?

 the commit ends the current transaction, and starts a new transaction from
 the Session's point of view.  However, no SQL or transactional directives
 are emitted until the first SQL statement is emitted via the Session (either
 via execute(), query() iteration, or flush). So there is no new database
 transaction if you commit then cease to use that Session further.

   session.close() // is it necessary?

 Not strictly although it removes any state left over in the session,
 thereby establishing any remaining objects as detached.  This is desirable
 since you might want to ensure that subsequent operations on those objects
 don't re-emit new SQL.

 
  Is the a Session instance directly associated to a Connection in the
 pool?

 Yes.  This is documented here:
 http://www.sqlalchemy.org/docs/orm/session.html#what-does-the-session-do

  With the default pool size of 5, after 5 call of the insert method, the
 connection_overflow would be used?

 No.  A single session uses one Connection per Engine at a time.  By
 default, it keeps one connection open until rollback(), commit(), or close()
 is called.
 http://www.sqlalchemy.org/docs/orm/session.html#managing-transactionsillustrates
  this.

  What's the time to a Session expire?

 it expires things when commit or rollback is called.This is also in the
 above docs.

 
  And just to finish. Why do we use remove() for the scoped_session instead
 of the close()?

 scoped_session offers all of the methods of the underlying Session via a
 proxy pattern, so you can call close() on scoped_session, which calls
 close() on the actual session, or you can call remove(), which emits close()
 then removes the Session object itself from the registry.  The latter has
 the advantage that any particular state established on the session, such as
 a Connection-based bind (see the example in
 http://www.sqlalchemy.org/docs/orm/session.html#joining-a-session-into-an-external-transaction),
  or other particular constructor options, are discarded.


  Shouldn't it be semantically identical only overrided for the contextual
 stuff?

 this would be scoped_session.close().   The distinction is discussed to
 some degree at
 http://www.sqlalchemy.org/docs/orm/session.html#lifespan-of-a-contextual-session.



 
  --
  You received this message because you are subscribed to the Google Groups
 sqlalchemy group.
  To post to this group, send email to sqlalchemy@googlegroups.com.
  To 

Re: [sqlalchemy] Session: close(), remove(), expire_all() and expunge_all()

2011-03-19 Thread Michael Bayer
if it helps, I was just talking to my co-author (SQLA book) about how when I 
first wrote versions 0.1, 0.2, my concept of the Session was pretty much what 
you thought here.   We hardy had expire at all, it seemed redundant versus 
expunge() to me (at that time called clear()). Only around 0.5 did I start 
getting my head around the expire with the transaction thing.There's a 
conceptual leap here about how to think about transactions (at least it was for 
me), and we really want to get this idea in the core of the book.


On Mar 19, 2011, at 12:48 PM, Israel Ben Guilherme Fonseca wrote:

 Thank you very much for the answers.
 
 No doubts for now. 
 
 2011/3/18 Michael Bayer mike...@zzzcomputing.com
 
 On Mar 18, 2011, at 2:55 PM, Israel Ben Guilherme Fonseca wrote:
 
  Hi everybody,
 
  I'm new with SQLAlchemy and I'm trying to understand better the Session 
  object.
 
  First of all, why the expire_all() exists?
 
 The purpose is to remove any database-loaded state from all current objects 
 so that the next access of any attribute, or any query execution, will 
 retrieve new state, freshening those objects which are still referenced 
 outside of the session with the most recent available state.   It is called 
 automatically upon commit() or rollback() assuming an autocommit=False 
 session, so that when the transaction, and its isolated environment, come to 
 an end, subsequent accesses of those objects will acquire new data from 
 whatever other transactions were committed subsequent to the previous 
 transaction.   expire_all() itself is useful when:
 
 - the session is used in autocommit=True mode, and new changes from other 
 transactions are desired.
 - against a database that does not support transactions, or perhaps within a 
 weakly isolated transaction, again to load changes from other transactions or 
 connections.
 - when SQL statements have been executed against the current transaction 
 using execute() which may have changed significant portions of loaded state 
 on the database.
 
 
  Shouldn't it be always better to expunge_all() instead? If it is expired, 
  at the use of the instance another query would be issued to reattach it 
  anyway, so why keep useless instances in the identity map (maybe i'm 
  wrong about this fact, i dont know exactly how the identity map works).
 
 They're not useless at all if you are performing operations upon them which 
 span the scope of multiple transactions, or have any of the above use cases, 
 and don't wish to re-establish a full graph of objects in memory.   In-memory 
 objects are essentially proxy objects to an underlying database transaction.  
 The Session mediates this relationship.
 
 
 
  Second, when we should call the close() method?
 
 when you wish to release the transactional and connection pool resources of 
 the Session and remove all objects.
 
 
  I dont think if i get it at all. Let's say that I have the following DAO:
 
  PersonDAO:
  def insert(self, person):
   session = Session()
   session.add(person)
   session.commit() // why the commit starts a new transaction? 
  should'n it only start again the next database access?
 
 the commit ends the current transaction, and starts a new transaction from 
 the Session's point of view.  However, no SQL or transactional directives are 
 emitted until the first SQL statement is emitted via the Session (either via 
 execute(), query() iteration, or flush). So there is no new database 
 transaction if you commit then cease to use that Session further.
 
   session.close() // is it necessary?
 
 Not strictly although it removes any state left over in the session, thereby 
 establishing any remaining objects as detached.  This is desirable since you 
 might want to ensure that subsequent operations on those objects don't 
 re-emit new SQL.
 
 
  Is the a Session instance directly associated to a Connection in the pool?
 
 Yes.  This is documented here:   
 http://www.sqlalchemy.org/docs/orm/session.html#what-does-the-session-do
 
  With the default pool size of 5, after 5 call of the insert method, the 
  connection_overflow would be used?
 
 No.  A single session uses one Connection per Engine at a time.  By default, 
 it keeps one connection open until rollback(), commit(), or close() is 
 called. 
 http://www.sqlalchemy.org/docs/orm/session.html#managing-transactions 
 illustrates this.
 
  What's the time to a Session expire?
 
 it expires things when commit or rollback is called.This is also in the 
 above docs.
 
 
  And just to finish. Why do we use remove() for the scoped_session instead 
  of the close()?
 
 scoped_session offers all of the methods of the underlying Session via a 
 proxy pattern, so you can call close() on scoped_session, which calls close() 
 on the actual session, or you can call remove(), which emits close() then 
 removes the Session object itself from the registry.  The latter has the 
 advantage that any