[ZODB-Dev] List of modified objects

Tim Peters tim at zope.com
Mon Dec 6 14:04:55 EST 2004


[Rad Widmer]
> Maybe this is related -- In my application I need to determine whether a
> transaction has *any* modified objects. At this time, I don't care what
> those objects are, I just need to know that there are some. For example,
> there is a Save button on the toolbar that I want to enable only if there
> is something to be saved. Also, when the user tries to quit the
> application, it's handy to know if there are unsaved objects so a prompt
> can be displayed (save/abandon changes).

Although the Subject on this thread is "list of modified objects", I've been
careful to talk about an API for iterating over modified objects.  Iterable
objects in Python solve a world of problems cleanly.  For example, if "it"
is an iterable object (or a method returning one), you can:

1. Create a list (if you want a list):

       a_list = list(it)

2. Simply iterate over it:

       for thing in it:
           process(thing)

3. Efficiently determine whether anything is available:

       something_exists = False
       for thing in it:
           something_exists = True
           break

> Since I'm using the latest version of ZODB, I found that checking the
> connections's _needs_to_join attribute periodically works for this.

Of course the leading underscore advises that this is a private attribute,
so there's no guarantee it will continue to work.  Note that it does a wrong
thing if you've committed a subtransaction, but haven't made any changes
since the subtxn commit.  In that case _needs_to_join will be true, despite
that you may have any number of uncommitted changes pending due to any
number of subtxn commits.

An "iterate over changed objects" API is also muddy in the presence of
subtxns (should it ignore objects already processed by subtxn commit?  if
not, and an object was modified by more than one subtxn, should it deliver
that object more than once?  what if an object was modified by a subtxn and
later at "top level"?).

If you don't mind closing and reopening connections, in 3.3 it would be
safer to do:

    try:
        my_connection.close()

    except ConnectionStateError:
        # Changes are pending (in subtxn, or at top level).
        # Put up a "Save" button -- whatever.  my_connection is
        # still open after ConnectionStateError.

    else:
        # No changes were pending.  Reopen the connection.
        my_connection = my_db.open()




More information about the ZODB-Dev mailing list