On Jul 27, 2011, at 3:34 AM, ammar azif wrote:

> Hi,
> 
> I am using SQLAlchemy 0.6.4 with postgres db. I have two tables - users and 
> addresses tables with addresses table having a foreign key constraint 
> referencing the users table. Each address record is identified by a unique 
> constraint key 'email_address'.
> In my test case, each user instance have a collection of addresses. For each 
> user instance, I want to delete every address instance in the addresses 
> collection that the user instance has and then add new address instances 
> (they may have the same unique key that the previously deleted address 
> instance had). The problem I am having now is that at the end of the flush 
> call, unique constraint error for 'email_address' from addresses table is 
> thrown even though delete operation is done earlier than insert. Looking at 
> the echo output, INSERTs are indeed done first than DELETEs. The work around 
> that I have now is to call flush() right after the deletion of address 
> instances in each user.
> 
> My question is - what is the precedence of insert, delete and update in 
> session flush? It would also be helpful if someone can explain the overview 
> of the mechanics of flushing in SQLAlchemy.
> Attached is the python script that I wrote to understand why this problem 
> mentioned above happens.


Right so, the unit of work was rewritten in version 0.6, because it was 
desperately needed, but also one issue I wanted to see if it could be solved 
was the one case that the UOW can't handle currently without direct 
intervention, that of the unique constraint that needs to be deleted before a 
new one is inserted.   

It should be noted that for an object where the primary key itself is the thing 
that might conflict for an outgoing / incoming situation, the UOW turns that 
operation into an UPDATE.    But for an arbitrary column with a unique on it we 
don't have the mechanics in place to do it that way, nor would I want to .    
Id much rather have a delete + insert be a DELETE + INSERT in all cases.

So with the UOW rewrite, its very clear cut how the order of steps is 
determined, and the architecture is fairly amenable to a strategy that would 
freely mix DELETE, INSERT and UPDATE.

However, I didn't go this far with the rewrite.   I tried a bit, trying to have 
the topological sort also take into account individual INSERTS that need to 
come before DELETES, instead of it being an overarching "two step" process,  
but there seemed to be a lot of really mindbendy types of cases where the fact 
that DELETES are unconditionally after the INSERT/UPDATEs makes things work out 
really well.    The 0.6 rewrite had the highest priority on not introducing any 
new bugs vs. the previous version, which had been very stable for a long time 
(although impossible to work with) so I didn't go further with that idea, at 
that time.      (There of course is no reason someone can't try to work with it 
some more)

The current scheme is INSERT/UPDATES first, DELETES second, and the original 
idea is mostly from Hibernate's procedure 
(http://docs.jboss.org/hibernate/core/3.3/reference/en/html/objectstate.html#objectstate-flushing),
 which I seem to recall was not as verbose as that particular description is 
now.

I have an architectural document I can send you under separate cover (it is not 
public yet).


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