8

Does updating an object after issuing session.commit() works correctly? Or do I need to refresh the object?

I think this is sufficient for the question, but I may provide more information to clear my question if needed.

Edit:

By updating, I meant setting some attribute i.e. column values of the object.

Shafiul
  • 2,832
  • 9
  • 37
  • 55

1 Answers1

13

Short answer: No, you do not need to refresh manually, sqlalchemy will do it for you.


It is useful to know when it happens, so below is short overview. From documentation of Session.commit():

By default, the Session also expires all database loaded state on all ORM-managed attributes after transaction commit. This so that subsequent operations load the most recent data from the database. This behavior can be disabled using the expire_on_commit=False option to sessionmaker or the Session constructor.

Basically, given you did not set expire_on_commit=False, object will be refreshed automatically as soon as you try accessing (reading, not setting) its attributes after session.commit().

my_obj = session.query(MyType).get(1)
my_obj.field1 = 'value1'
session.commit() # will commit and expire my_obj

my_obj.field1 = 'new value' # object is still the same, but field is updated
print my_obje.field1 # at this point SA will first refresh the object from the database; and make sure that new values for changed fields are applied

In fact, if you enable logging, you will see that sqlalchemy emits new SELECT statements as soon as you access (read) persistant instances' attributes.

van
  • 74,297
  • 13
  • 168
  • 171
  • I think you misread me? I'm asking about **updating** an object, that is updating one/some column values. Can you please clarify because I think my choice of the word 'updating' could be misleading. – Shafiul Apr 04 '14 at 17:13
  • Ok, this is not the same my answer covers, but large part of it is still relevant. So, basically, after the line in my answer (`my_obj.field1 = 'new value'`), only in memory will this change happen. in order to have you database reflecting this change, you will have to call `session.commmit()` once again. Does this cover it? – van Apr 04 '14 at 18:51
  • @van I'm experiencing the exact opposite, setting an attribute after the `session.commit()` still updates the database with that new attribute, even though I do not run a `session.commit()` after. So it seems perhaps something change even in regards to updating in the later versions? – Andreas Klintberg Dec 16 '20 at 08:33
  • @AndreasKlintberg, this is very strange and i would not expect this behavior to have changed. Just a guess: any chance you are running inside the "context manager" which auto-commits on exit unless there are errors? For, example, flask-sqlalchemy would do this for the web requests sessions. – van Dec 18 '20 at 06:55
  • 1
    Yes sorry I messed up. Wasn't using the correct session :/ thanks for helping out though! And yes you are right, it was auto-committing as well using sqlalchemy-graphene :) – Andreas Klintberg Dec 19 '20 at 06:12