Dňa pondelok, 18. februára 2013 18:54:22 UTC+1 Michael Bayer napísal(-a):
>
>
>
> On Feb 18, 2013, at 12:10 PM, Juraj Variny <[email protected] <javascript:>> 
> wrote:
>
> Hello,
>
> I should have expected refresh() to have problem with dirty objects, but 
> if it isn't a bug, maybe it should be at least documented.
>
> To explain whole situation and why do I call the refresh() at all: I have 
> Account persistent class, with balance property. When doing processing, I'm 
> locking the row whenever it is necessary to update it (to not lock more 
> rows than necessary), like:
>
> def update(acct,...):
>     DBSession.refresh(acct,lockmode='update')
> #update balance, add transaction record,return
>
> The problem is, this function can be called multiple times in one session 
> and subsequent refresh calls throw out unsaved changes. So far I have fixed 
> it by placing DBSession.flush() calls. But calling flush() in the middle of 
> processing implies risk of problems with unmatched constraints (not fully 
> fleshed out data). Another idea is to mark already locked objects so that 
> refresh() is called only first time in a transaction. Such reentrant 
> behavior may be useful to have, what do you think?
>
>
> if you just want to emit a SELECT .. FOR UPDATE you can just emit that 
> directly.   If you specify with_lockmode() on query(), the get() will emit 
> a SELECT unconditionally:
>
> session.query(Account).with_lockmode('update').get(my_account.id)
>
> it would be more efficient to not emit this SELECT more times than needed 
> though this is easy enough to roll on top of a session, like a 
> "lock_object()" function...can be tracked with events, here's also 
> generalized:
>
> from sqlalchemy import event
> from sqlalchemy.orm import Session, object_session, object_mapper
>
> @event.listens_for(Session, "after_begin")
> def setup_lock_collection(session, *args):
>     session._locked = set()
>
> @event.listens_for(Session, "after_commit")
> @event.listens_for(Session, "after_rollback")
> def clear_lock_collection(session):
>     session._locked.clear()
>
> def lock_object(obj):
>     session = object_session(obj)
>     mapper = object_mapper(my_account)
>     pk = mapper.primary_key_from_instance(my_account)
>     if (mapper, pk) not in session._locked:
>         session.query(mapper).with_lockmode('update').get(pk)
>         session._locked.add((mapper, pk))
>
> Nice, looks exactly like what I need! I guess my_account should be changed 
into obj ?

-- 
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to