session.add() or session.update() ? (NEWBIE)

6,873 views
Skip to first unread message

Marcin Krol

unread,
Mar 27, 2009, 6:57:38 AM3/27/09
to sqlal...@googlegroups.com
Hello everyone,

I have tested that session.add(changed_sqla_object) in at least one
context (when the object with id of changed_sqla_object already exists
in the db) does issue UPDATE sql query and updates the object in the
database.

However, there's also session.update() method. Help on this says:

> update(self, instance) method of sqlalchemy.orm.session.Session instance
> Bring a detached (saved) instance into this ``Session``.

Meaning this updates session with the saved object data, and it's not
that the *changed* object's data that is updated in database?

>
> Use session.add()

To do what?

>
> If there is a persistent instance with the same instance key, but
> different identity already associated with this ``Session``, an
> InvalidRequestError exception is thrown.
>
> This operation cascades the `save_or_update` method to associated
> instances if the relation is mapped with ``cascade="save-update"``.

In general, the question: is it safe to use session.add(changed_object)
in *all of the circumstances*?

Regards,
mk

Michael Bayer

unread,
Mar 27, 2009, 1:00:08 PM3/27/09
to sqlal...@googlegroups.com

update(), save_or_update(), save() are all deprecated. add() places an
object in the session in all cases, using the persistence information
already associated with the object to determine INSERT or UPDATE. this
means if you just make a new Foo(id=some id), that's transient -
SQLAlchemy didn't load it. It will be INSERTed.

Keep in mind that the Session maintains an identity map of all unique
primary keys already loaded into memory, as well as the state which was
received from the database. For this reason, you generally can't just put
an object in the session with some arbitrary data, and expect it to "take
the place" of the actual row that would be loaded by the transaction.
SQLAlchemy wouldn't know what to do with it since it has no idea what
changes have been made to this row versus what is already present.

If you'd like to create a new Foo() with a primary key that may or may not
already exist in the database, you want to merge the state of that object
with one that is produced by the Session. Use session.merge() for this
use case. this will load the existing object from the current
transaction, if any, and merge the state of your outside object with it,
returning the instance. The instance you pass to it remains unchanged and
outside the session.


Reply all
Reply to author
Forward
0 new messages