Want to ask you guys opinions about this :In the spirit of separating 
lifecycle of sqlalchemy session from actual operations on db, sqlalchemy 
suggests the following pattern (
http://docs.sqlalchemy.org/en/rel_0_9/orm/session_basics.html ):


### this is a **better** (but not the only) way to do it ###
class ThingOne(object):
    def go(self, session):
        session.query(FooBar).update({"x": 5})
class ThingTwo(object):
    def go(self, session):
        session.query(Widget).update({"q": 18})
def run_my_program():
    session = Session()
    try:
        ThingOne().go(session)
        ThingTwo().go(session)

        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()


My question is: what if we have ThingThree:

class ThingThree(object):

    def go(self, session):

          session.query(Widget).all()

The point is: if the operation is Query only (not write), should we also wrap 
it with the session scope. My understanding is: a transaction is started even 
if it is just a Query, and if it fails, the state of identityMap maintained by 
session will be changed even if database is still unchanged, therefore, we 
probably still need session.rollback() even if it is just a Query, since that 
will also bring the identitymap state back to the normal state before the 
Query. 

However, i am not sure about this. The downside of this is, if this is not 
necessary, then we introduce unnecessary wrapping around Query.

BTW, there is another example 
at:http://docs.sqlalchemy.org/en/rel_0_9/orm/session_transaction.html#session-external-transaction

engine = create_engine("...")
Session = sessionmaker(bind=engine)
# new session.   no connections are in use.
session = Session()try:
    # first query.  a Connection is acquired
    # from the Engine, and a Transaction
    # started.
    item1 = session.query(Item).get(1)

    # second query.  the same Connection/Transaction
    # are used.
    item2 = session.query(Item).get(2)

    # pending changes are created.
    item1.foo = 'bar'
    item2.bar = 'foo'

    # commit.  The pending changes above
    # are flushed via flush(), the Transaction
    # is committed, the Connection object closed
    # and discarded, the underlying DBAPI connection
    # returned to the connection pool.
    session.commit()except:
    # on rollback, the same closure of state
    # as that of commit proceeds.
    session.rollback()
    raise

in the above example, they put "try" before session.query(Item).get(), instead 
of right before "item1.foo='bar'), this kind of implies that query could also 
need to be rollbacked when it fails. However, they did not explicitly say that. 

Basically, my question is what is the best practice for query only.

Please help! thanks a lot!


Hao Yan

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to