Brilliant, the after_flush event sounds like the way to go. I guess my
event handlers would be:

after_begin:
  session.info.clean = True
after_flush:
  if new, dirty, deleted:
    session.info.clean = False
after_commit:
  session.info.clean = True
after_rollback:
  session.info.clean = True

Then in my context manager I just need to check both (current session.new
.dirty .deleted) and (my new session.info.clean attribute) to determine if
the session has been left with uncommitted changes. Does that sound like
what you'd expect? Are there any other events you can think of that I'd
need to handle/be careful of?

Thanks a lot for your help!

Tom

On 9 October 2014 17:42, Michael Bayer <mike...@zzzcomputing.com> wrote:

>
> On Oct 9, 2014, at 12:16 PM, Tom Dalton <tom.dal...@fanduel.com> wrote:
>
>
> Thanks for the reply. I saw the session transaction events stuff but I'm
> not sure that they help me (correct me if I'm wrong). I believe a
> transaction will exist if I run *any* query, not just one that modifies
> data. Also, the docs imply that a session will effectively always have a
> transaction when using autoflush mode. Finally, the after_begin event only
> fires once. So I'd have no way to tell the difference between the session
> state after the following 3 scenarios:
>
> 1. (implicit) begin, select, update, select, (autoflush)
> 2. (implicit) begin, select, (autoflush)
> 3. (implicit) begin, select
>
> In my use case, I want to detect the uncommitted (but flushed) changes and
> throw an error, but cases 2 and 3 are 'ok’.
>
>
> OK, so catch after_begin, as well as after_flush - inside of after_flush,
> check a boolean for .new, .dirty, .deleted, that will tell you if the flush
> actually rendered any changes (which usually it has, you can just record
> after_flush() happening at all as “changes were probably emitted”).
>
>
>
> Even disabling autoflush doesn't help, since I'd still be unable to tell
> if the (erroneous/buggy) code had done an explicit flush without a
> subsequent rollback or commit.
>
> I'm feeling a bit stuck, but I assume this information must exist in
> SQLAlchemy somewhere, since if you do:
>
> 4. (implicit) begin, select X, update X, flush, rollback
>
> then SQLAlchemy must 'know' which instance's (flushed) changes have been
> rolled back in order to change those instances' state (I think in the above
> example, it would mark X as detached?). The problem is I don't know where
> or how it's maintaining that info…
>
>
> it maintains that in session.transaction._new, session.transaction._dirty,
> session.transaction._deleted, but these are weak referencing (because if
> references to the object are lost on the outside, we forget about it) so
> aren’t guaranteed to show you that something definitely didn’t happen.
>  (hence events the best way to go)
>
>
>  --
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at http://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to