On Feb 6, 2010, at 2:16 PM, Kent wrote:

> There might/probably is a better way to achieve what I am trying to
> achieve.  Let me explain:
> 
> I've got a typical Customer/Order/Orderdetail relation.
> 
> merge() appeals to me because it does most all the same work I'd
> otherwise need to do.  I get passed to me an "Order" object will the
> customer object and the details objects.
> 
> Now, when I run merge, if there are any changes to the customer, these
> get automagically updated.  If a line is missing, it is automatically
> deleted.  If a new line exists, it is automatically inserted.
> 
> session.merge() does all this.
> 
> However, the above is a bit too simplified.  If the Customer's primary
> key is not supplied, I need to create this in a special way (not from
> a sequence) and then insert it.  In this case, I don't even want merge
> to *attempt* to get() from the database first because if, by chance,
> the customerid I construct is already in use, I do not want to
> accidentally update that record, I *want* the database to complain on
> the INSERT that the primary key already exists.
> 
> Same with the order and orderdetails.  If an orderdetail is supplied
> to me without a primary key, I would like to choose the next
> appropriate primary key and INSERT for that particular record, so that
> (if something is messed up or a race condition exists with another
> instance of the program choosing the same primary key) I get a
> database error instead of merge() accidentally updating that other
> record.
> 
> I don't want to give up the benefits of merge() by programmatically
> figuring this out myself.  In other words, if I add() to the session
> all the lines I *know* should be INSERTs then I need to work out all
> the other magical things merge() is doing for me (like deleting
> missing lines).

your primary key generation scheme here requires manual steps - you create a 
new identifier, then you need to check that it doesnt exist.   merge() and 
add() won't do this for you, so you do this yourself as needed with your given 
objects, and assign those identifiers to the objects.   Then you can proceed to 
merge() them normally.  There is no "trick" that will do this for you.

> 
> I tried seeing what would happen if I just called session.add() for
> the cases of an INSERT and then calling session.merge() for the entire
> cascading order(customer/details), but when I tried that I got:
> New Instance conflicts with persistent instance type error.
> 
> I assume this means: you tried to session.add() and object and now I
> just looked up this same instance during the session.merge().

unless I'm forgetting something (possible), merge() should not be able to 
produce that error, since it is not placing any new instances in the session 
unless that identity did not exist.   Did you turn off autoflush perhaps ?  a 
flush needs to occur after your add() so that the pending object now becomes 
persistent (this is why Session does its work in a transaction, in case you're 
concerned about "writes").


-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@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