Re: [sqlalchemy] Implementing a "radio button" behavior?

2011-09-08 Thread Vlad K.


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.



Re: [sqlalchemy] Implementing a "radio button" behavior?

2011-09-08 Thread Michael Bayer

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.



Re: [sqlalchemy] Implementing a "radio button" behavior?

2011-09-08 Thread Vlad K.


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.


So, in short, I'm doing this:

1. select row or new
2. assign some values to it
3. issue an update to a group of other rows (this should happen FIRST)
4. merge the row with db, flush, commit. (this should happen SECOND)

What I'm getting:

1. SELECTed row data
2. UPDATE on changed values (implicit flush of dirtied session data)
3. UPDATE as expected in step 3 above
4. COMMIT



.oO V Oo.


On 09/08/2011 10:04 PM, Michael Bayer wrote:

On Sep 8, 2011, at 3:32 PM, Vlad K. wrote:


For example the following:

row = session.query(Model).filter_by(pkey=pkey_value).first() or Model()
row.some_field = 123;
...


session.query(Model).filter_by(nonprimary_key=some_value).update({...}, false)
session.merge(row)
session.flush()

When flush() gets called, the merge() is executed (query sent to DB) before the 
update called above it, in this particular example.

That isn't correct, query.update() emits UPDATE immediately.   Do you have a 
SQL log illustrating what is being emitted ?


--
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.



Re: [sqlalchemy] Implementing a "radio button" behavior?

2011-09-08 Thread Michael Bayer

On Sep 8, 2011, at 3:32 PM, Vlad K. wrote:

> 
> For example the following:
> 
> row = session.query(Model).filter_by(pkey=pkey_value).first() or Model()
> row.some_field = 123;
> ...
> 
> 
> session.query(Model).filter_by(nonprimary_key=some_value).update({...}, false)
> session.merge(row)
> session.flush()
> 
> When flush() gets called, the merge() is executed (query sent to DB) before 
> the update called above it, in this particular example.

That isn't correct, query.update() emits UPDATE immediately.   Do you have a 
SQL log illustrating what is being emitted ?



> 
> 
> 
> .oO V Oo.
> 
> 
> On 09/08/2011 04:37 PM, Michael Bayer wrote:
>> On Sep 8, 2011, at 9:32 AM, Vlad K. wrote:
>> 
>>> 
>>> As a "by the way" to this question, I've noticed that the order of queries 
>>> given before flush() is not preserved for the flush(). Any way to enforce 
>>> the order?
>> Trying to parse what this means.   Suppose you did a single SELECT, loaded 
>> five objects.  Then changed them and did a flush.   What is the "order of 
>> queries" to be preserved?
>> 
>> Guessing, perhaps you mean, the order in which a particular object became 
>> present in the Session, that's the order in which UPDATE statements should 
>> be emitted.UPDATE statements are in fact ordered in terms of the primary 
>> key of the row.   The reason for this is to minimize the chance of 
>> deadlocks.Process A and process B both need to update primary key 1 and 
>> 2 in a table.   If process A starts with 1 and process B starts with 2, you 
>> have a deadlock.So an ordering that is deterministic across 
>> transactions, where PK ordering is a pretty good assumption in most cases, 
>> is the best behavior here.
>> 
>> If you need UPDATE statements in a specific order, you can A. emit flush() 
>> specifically against a Session in which you're controlling what's "dirty", 
>> B. use query.update(), C. use the Core SQL language instead of the ORM for 
>> this particular series of operations (though query.update() likely a happy 
>> medium).
>> 
>> 
>> 
>> 
> 
> -- 
> 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.
> 

-- 
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.



Re: [sqlalchemy] Implementing a "radio button" behavior?

2011-09-08 Thread Vlad K.


For example the following:

row = session.query(Model).filter_by(pkey=pkey_value).first() or Model()
row.some_field = 123;
...


session.query(Model).filter_by(nonprimary_key=some_value).update({...}, 
false)

session.merge(row)
session.flush()

When flush() gets called, the merge() is executed (query sent to DB) 
before the update called above it, in this particular example.




.oO V Oo.


On 09/08/2011 04:37 PM, Michael Bayer wrote:

On Sep 8, 2011, at 9:32 AM, Vlad K. wrote:



As a "by the way" to this question, I've noticed that the order of queries 
given before flush() is not preserved for the flush(). Any way to enforce the order?

Trying to parse what this means.   Suppose you did a single SELECT, loaded five objects.  
Then changed them and did a flush.   What is the "order of queries" to be 
preserved?

Guessing, perhaps you mean, the order in which a particular object became 
present in the Session, that's the order in which UPDATE statements should be 
emitted.UPDATE statements are in fact ordered in terms of the primary key 
of the row.   The reason for this is to minimize the chance of deadlocks.
Process A and process B both need to update primary key 1 and 2 in a table.   
If process A starts with 1 and process B starts with 2, you have a deadlock.
So an ordering that is deterministic across transactions, where PK ordering is 
a pretty good assumption in most cases, is the best behavior here.

If you need UPDATE statements in a specific order, you can A. emit flush() specifically 
against a Session in which you're controlling what's "dirty", B. use 
query.update(), C. use the Core SQL language instead of the ORM for this particular 
series of operations (though query.update() likely a happy medium).






--
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.



Re: [sqlalchemy] Implementing a "radio button" behavior?

2011-09-08 Thread Michael Bayer

On Sep 8, 2011, at 9:32 AM, Vlad K. wrote:

> 
> 
> As a "by the way" to this question, I've noticed that the order of queries 
> given before flush() is not preserved for the flush(). Any way to enforce the 
> order?

Trying to parse what this means.   Suppose you did a single SELECT, loaded five 
objects.  Then changed them and did a flush.   What is the "order of queries" 
to be preserved?

Guessing, perhaps you mean, the order in which a particular object became 
present in the Session, that's the order in which UPDATE statements should be 
emitted.UPDATE statements are in fact ordered in terms of the primary key 
of the row.   The reason for this is to minimize the chance of deadlocks.
Process A and process B both need to update primary key 1 and 2 in a table.   
If process A starts with 1 and process B starts with 2, you have a deadlock.
So an ordering that is deterministic across transactions, where PK ordering is 
a pretty good assumption in most cases, is the best behavior here.

If you need UPDATE statements in a specific order, you can A. emit flush() 
specifically against a Session in which you're controlling what's "dirty", B. 
use query.update(), C. use the Core SQL language instead of the ORM for this 
particular series of operations (though query.update() likely a happy medium).




-- 
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.