On Jan 31, 2014, at 5:24 PM, lars van gemerden <[email protected]> wrote:

> Hi, all
> 
> I am running into these 2 errors and have run out of ideas what to do about 
> it (also because i don't what they mean); They seem to happen in exactly the 
> same circumstances.
> 
>     mapper, table, update)
>   File "build\bdist.win32\egg\sqlalchemy\orm\persistence.py", line 514, in 
> _emit_update_statements
>     (table.description, len(update), rows))
> StaleDataError: UPDATE statement on table 'Company' expected to update 1 
> row(s); 0 were matched.

this means an object was meant to be UPDATEed via the ORM, however the row 
which is the target of the UPDATE is missing.  Either the primary key of this 
row changed somehow, or the row was deleted, *or* the row is not visible to 
your transaction (this seems to be your case).

Here’s the DELETE case:

sess = Session()

m1 = MyObject()
sess.add(m1)
sess.flush()

# out of band DELETE, ORM has no clue
sess.execute(“DELETE FROM my_object WHERE id=:id”, {“id”: m1.id})

# modify object
m1.foo = ‘bar’

# row is gone, boom
sess.flush()


> 
> File 
> "C:\python27\lib\site-packages\sqlalchemy-0.8.3-py2.7-win32.egg\sqlalchemy\orm\loading.py",
>  line 606, in load_scalar_attributes
> sqlalchemy.orm.exc.ObjectDeletedError: Instance '<Company at 0x5e0d550>' has 
> been deleted, or its row is otherwise not present.


same idea, object is expired:

m1 = MyObject()
sess.add(m1)

# flush m1, also expire it
sess.commit()

# out of band DELETE, ORM has no clue
sess.execute(“DELETE FROM my_object WHERE id=:id”, {“id”: m1.id})

# row is gone, boom
print m1.foo


> 
> What i do is:
> 1 make a new object (mapped)-> obj1
> 2 add it to a session -> session1 

> 3 start another session -> session2 
> 4 do a get(id) on session2 (which should result in access to the database, 
> since i just started the session) -> obj2 
> 5 close session2
> 6 do obj1.someattr.append(obj2)
> 7 do session1.commit()
> 8 get the first ERROR above 

this description isn’t specific enough to understand the issue.  What does “add 
it to a session” mean, did you flush that session?  was an INSERT emitted?  did 
you commit the transaction?  When you attempt to use “obj2” with obj1, you mean 
you are using the detached obj2 ?   What is the “id” you’re using get() on, is 
that the “id” that you know was created in #2 ?

Basically your problem comes down to sharing rows between transactions where 
those transactions aren’t aware of the rows you’re referring to (which is due 
to transaction isolation, see 
http://en.wikipedia.org/wiki/Transaction_isolation).  When you move an object 
between sessions, you should generally use merge() which will emit a SELECT for 
that row first.

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

Reply via email to