How to tell in advance if session.flush() will do anything?

62 views
Skip to first unread message

Russ

unread,
Dec 19, 2012, 12:21:08 PM12/19/12
to sqlal...@googlegroups.com
I've got some code where I want to assert that the ORM session is perfectly clean. ie: I want to know if a flush() will emit SQL.

What is the best way to determine this?

Right now I'm simply checking like this:

if session.new or session.dirty or session.deleted:
    print "flush() actions pending!"

I believe this is a complete way to check this, but I'm wondering if there is a more efficient, possibly single point, way to check this.  One reason for asking this is that the docs indicate for session.dirty that "this collection is now created on the fly each time the property is called"... but when all I want to know is "is flush() going to do anything?" it seems a waste to generate that collection.

Thanks,
Russ

Michael Bayer

unread,
Dec 19, 2012, 12:29:50 PM12/19/12
to sqlal...@googlegroups.com
the Session uses the method session._is_clean() internally to check if going through the flush() steps is warranted, which is roughly equivalent to the check you're doing, though it is doing less work to make this decision - if you take a look at what it does, compared to the implementation for .new, .dirty, .deleted, you save on the iteration of those collections and the translation of all the InstanceState objects into userland objects.

There's another caveat, which is that even if _is_clean() is false, that's not a total guarantee that SQL will be emitted on flush. If you changed one object attribute to be the same value that it already was, for example, that's a "dirty" event, but when the flush runs through, it will see no net change and not emit an UPDATE.

This is part of the reason _is_clean() at the moment still has an underscore. Easier to keep the underscore than to promise a completely predictable usage pattern :).


Russ

unread,
Dec 19, 2012, 1:01:55 PM12/19/12
to sqlal...@googlegroups.com
On Wednesday, December 19, 2012 12:29:50 PM UTC-5, Michael Bayer wrote:
the Session uses the method session._is_clean() internally to check if going through the flush() steps is warranted, which is roughly equivalent to the check you're doing, though it is doing less work to make this decision

_is_clean() looks perfect, thanks!
 
There's another caveat, which is that even if _is_clean() is false, that's not a total guarantee that SQL will be emitted on flush.   If you changed one object attribute to be the same value that it already was, for example, that's a "dirty" event, but when the flush runs through, it will see no net change and not emit an UPDATE.

No problem... this is actually perfect since it still means that someone *tried* to alter something in the session, which is what I'm really after.
 
This is part of the reason _is_clean() at the moment still has an underscore.   Easier to keep the underscore than to promise a completely predictable usage pattern :). 

I'm fine with that, too... as long as the other "part[s] of the reason" for the underscore don't end up at "this method is totally not reliable for use in future versions since it could change at any time." :)

Russ

Russ

unread,
Dec 19, 2012, 1:22:16 PM12/19/12
to sqlal...@googlegroups.com
Whoops - _is_clean() doesn't make it up to a ScopedSession...

Digging into why this is the case I see the registry pattern in there.  Is it a safe/valid cheat to access the registry directly and do this?

if my_scoped_session.registry()._is_clean():
    print "an attempt to modify the session was made!"

Russ

Michael Bayer

unread,
Dec 19, 2012, 1:25:02 PM12/19/12
to sqlal...@googlegroups.com
just call upon the scoped_session itself, it has __call__() for this purpose:

scoped_session()._is_clean()

the current docs are carefully written to explain all this: http://docs.sqlalchemy.org/en/rel_0_8/orm/session.html#contextual-thread-local-sessions


Reply all
Reply to author
Forward
0 new messages