You guys have done some great work, thanks.  (How many developers are
you?)



On Feb 8, 11:50 am, "Michael Bayer" <mike...@zzzcomputing.com> wrote:
> Kent wrote:
> > Thank you again for your response and time.
>
> > I think a different approach may be better for me, but was hoping for
> > your input.
>
> > I think I'd like to let session.merge() work out whether it is going
> > to do an add() vs. update properties on the object retrieved
> > from .get()
>
> > Then, after merge(), but before the flush(), I can change anything I
> > need/run validations and populate primary keys, etc.
> > Then I can call flush().
>
> > I think this approach should work for me, but here is my question:
> > When merge() returns the merged object, how can I tell whether a
> > new_instance was created vs get() having returned an existing object?
>
> "obj in session.new"
>
>
>
> > Can I inspect the object (and its children) to find this out?  (Am I
> > really wondering if this object is persistent? How do I determine
> > this?) Or can I inspect the session to determine this?
>
> > Can I tell which children are "scheduled" for deletion by inspecting
> > the session or merged object somehow?
>
> "obj in session.deleted"
>
>
>
> > Lastly, by the time merge() returns, we have no reference any longer
> > to the original data, only the merged data.  If, for my validations, I
> > wanted to compare the old property to the new property, can you
> > recommend an approach to this?  I'd rather not hit the database twice,
> > since merge is going to look up the data anyway.
>
> whatever Python state you send into merge() remains unchanged.   the "new"
> data is what is returned. So you could compare those two things.
> Alternatively, whats returned also represents in itself a "diff" of the
> data you passed into merge vs. what was already in the DB.  So if you
> wanted to look at individual attributes on the newly merged objects to see
> what changed:
>
> from sqlalchemy.orm import attributes
> history = attributes.get_history(instance, "somekey")
>
> this returns a tuple of (new, unchanged, deleted).   For a scalar, each
> member is a one-item tuple.
>
>
>
> > I was hoping I might be able to extend Session or override its
> > behavior so as to keep a copy of the object returned from .get()
> > before it merges the changes.
>
> > Input and ideas for me?
>
> > Thanks very much in advance,
> > Kent
>
> > On Feb 6, 5:47 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
> >> 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.
>
>

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