Yes, I earlier said it was merge() that took effect before update() because that's how it looked like (didn't know about autoflush). Putting a sleep before update() and merge() showed that merge() issued no SQL because the autoflush (as you say) of the update() practically synced the session with the database.

The update() does technically affect the row in teh database which is already selected and in session and dirtied, but not via primary key. What I'm doing is this:

1. select a row into session
2. assign some data to it (dirties it)
3. if this row's "flag" property is set to true, first set flag=false to all rows in the same group (the Update), this one included
4. now merge this row

Or via plain SQL:

1. SELECT ...
2. UPDATE tablename SET flag=false WHERE group_id=123;
3. UPDATE tablename SET flag=true, ... WHERE primary_key=456;


The end result is that only one row in the group can have the flag set to true. The blanket set flag=false is imho faster and cleaner than finding out which row in the group has the flag and then updating just that one row, before our main model row. No?

I thought that session was only tracking changes via primary key so it never occurred to me that session would realize it is holding a row that's about to be updated, so it issues a flush first... Or am I misunderstanding what is going on here?

Turning autoflush off did the trick and the updates are now in order. Many thanks for your help!



.oO V Oo.


On 09/09/2011 12:17 AM, Michael Bayer wrote:
On Sep 8, 2011, at 6:00 PM, Vlad K. wrote:

Yes that's how I know the order of events. I just checked the logs again and put some 
sleep() between update() and merge(). It appears that the update() does some kind of 
implicit flush because that "commits" the dirtied properties of the row 
instance BEFORE the update is issued, so that when merge() comes, everything appears in 
sync to the session.
that's autoflush, which is part of the update() (earlier you said the merge() 
was taking effect before the update()).    Its a little strange to change an 
attribute on an object that dirties it for update, then manually do an update() 
that affects the same object - is it the same attribute you're trying to update 
there ?

Anyway, turn off autoflush.   Here's some recipes to do that as needed:

http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DisableAutoflush





--
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 unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to