On 9/21/2010 6:10 PM, Michael Bayer wrote:

On Sep 21, 2010, at 7:04 PM, Michael Hipp wrote:

On 9/21/2010 7:31 AM, Michael Hipp wrote:
I need to "empty" an item (row). I thought to do this:

new = Item() # create a new empty object
new.id_ = old.id_ # copy certain other fields also
self.session.expunge(old)
self.session.add(new)
self.session.commit()

But it seems SA still tries to save it with an INSERT. (I thought the presence
of the PK was what determined that.)

Is there some way to "blank" a record and save it back with the same PK and a
few other select fields that need to be kept?

I continue to play with this. It reads like 'merge' would do exactly what I 
want, but I must be misunderstanding it.
http://www.sqlalchemy.org/docs/orm/session.html#merging

Changing the 'session.add' line to 'session.merge' still produces
  IntegrityError: duplicate key value violates unique constraint

Trying it with and without the 'expunge' line just changes the error to
  New instance ... conflicts with persistent instance

Can anyone suggest an approach to "empty" a record?

new = Item()
new.id = old.id
new.some_foo = 'bar'
new = session.merge(new)
session.commit()

the full primary key attributes of "new", above the single attribute "id", must be 
populated.   If an integrity error is raised, this may suggest an INSERT is occuring, which you should verify 
by echoing SQL and then ensure that the primary key fields of "new" are fully filled in and that 
such a row actually exists, again echoing SQL should reveal a SELECT statement for the row and if 
echo='debug' you will see the row come back.

If the integrity error is raised and the statement is observed to be an UPDATE, 
then you are updating a column to a value that is already present in some other 
row in the table, where the column has a UNIQUE constraint on it.

Thanks. I stared at what you wrote for a long time as I couldn't see anything materially different in it from what I wrote.

But what's happening here seems weird. An abbreviated version of my model looks like this:

class Car(Base):
    __tablename__ = 'cars'
    id_ = Column(Integer, primary_key=True)
    auct_id = Column(Integer, ForeignKey('auctions.id_'), nullable=False)
    auction = relationship('Auction', backref=backref('cars', order_by=lane))

If I do this, it fails trying to do an 'INSERT' on the new Car.
    new.auction = old.auction

If I change that to:
    new.auct_id = old.auct_id

It attempts an UPDATE as expected. (I don't understand why that auct_id/auction column would have that effect; it's not a primary key.)

But that won't work because new.auction is still None so when I attempt a commit it fails with:

Exception: IntegrityError: (IntegrityError) null value in column "auct_id" violates not-null constraint 'UPDATE cars SET make=%(make)s, auct_id=%(auct_id)s, version_id=%(version_id)s WHERE cars.id_ = %(cars_id_)s AND cars.version_id = %(cars_version_id)s' {'auct_id': None, 'make': '', 'cars_version_id': 1, 'cars_id_': 2, 'version_id': 2}

Why is 'auction' causing it to do an INSERT and how can I set it?

Thanks,
Michael

--
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to