[ZODB-Dev] What causes a persistent object to be "broken"?

Tim Peters tim at zope.com
Thu Mar 3 01:18:12 EST 2005


[kw_odonian]
> I'm using a PersistentMapping and have noticed that one of the mappings
> shows the following, after creating and committing a one item mapping:

I assume you're using some ZODB in the 3.3 (not 3.2 or 3.1) line.  Scream if
that's wrong.

> {u'test_system': <persistent broken __main__.System instance
> '\x00\x00\x00\x00\x00\x00\x00\x1a'>}
>
> Here __main__.System is a custom datatype that's a composite of smaller
> objects, that are themselves persistent.  In general, why does a
> persistent object become "broken"?   What needs to be done to fix this?
> Any help would be appreciated,

It's "a new feature" in 3.3.  I can't find any user-level docs for it.  If
that's so, reading the docstrings in broken.py, and the tests in
testBroken.py, is the same thing I'd do to try to figure out its intent.

It looks like one these gets created when you attempt to load an object of a
persistent class from the database, but the module containing the object's
class can't be found, or the original module can be found but the class no
longer exists in that module.

In earlier ZODBs, those would lead to an ImportError or AttributeError
exception.  I'm not sure why it was decided to turn such cases into "broken
objects" instead (Jim? Jeremy?).

Quick example:

>>> import ZODB
>>> import transaction
>>> from persistent import Persistent

Create a persistent class.

>>> class C(Persistent):
...     pass

Create an instance, and store it off the root object of a new database.

>>> from ZODB.FileStorage import FileStorage
>>> st = FileStorage('temp.fs')
>>> db = ZODB.DB(st)
>>> cn = db.open()
>>> rt = cn.root()
>>> rt['c instance'] = C()
>>> transaction.commit()

Verify we can load it again, via a different connection.

>>> cn2 = db.open()
>>> cn2.root()['c instance']
<__main__.C object at 0x00954BB0>

Now destroy the class object.  It's impossible to load the instance again
after doing so, because the code for the class can't be found anymore.

>>> del C
>>> cn3 = db.open()
>>> cn3.root()['c instance']
<persistent broken __main__.C instance '\x00\x00\x00\x00\x00\x00\x00\x01'>
>>>

> What needs to be done to fix this?

Ensure that the code for class System exists in module __main__ at the time
you try to load a persistent object of class __main__.System.



More information about the ZODB-Dev mailing list