[Zope3-Users] Re: Evolution of ZoDB after changing python modules structure (moving content classes to another module)

Aleksander Kowalczyk thealx at poczta.onet.pl
Sun Jun 10 03:14:24 EDT 2007


On 6/8/07, Alek Kowalczyk <thealx at poczta.onet.pl> wrote:
>
> Alek Kowalczyk <thealx at ...> writes:
>
> >
> > Hi,
> > I moved my content class from mypackage.mymodule.MyContentClass into
> > mypackage.mysubpackage.mymodule.MyContentClass.
> > But when started Zope and went to visit an object I have previously
> created (of
> > MyContentClass), I get:
> > ComponentLookupError: ((<persistent broken
> mypackage.mymodule.MyContentClass
> > instance '\x00\x00\x00\x00\x00\x00\x02q'>,
> > <zope.publisher.browser.BrowserRequest instance
>
I found a quite well working solution on
> http://mail.zope.org/pipermail/zodb-dev/2006-September/010382.html
>
> There was only one issue: this solution assumes that we have given a DB,
> while
> Zope evolve method receives already open connection. Unfortunately
> classFactory
> from DB is cached in Connection's private fields in constructor.
> Because of that I could not assign my custom 'renaming' class factory
> using:
>
> def evolve(context): #won't work!
>     context.connection.db().classFactory = myClassFactory
>
> Instead I had to do some dirty private fields substitution in Connection's
> ObjectReader:
>
> def evolve(context): #this works nice
>     context.connection._reader._factory = myClassFactory


I shouldn't announce success too early. The solution works but only during
first Zope run (i.e just after evolving the schema).
Although classFactory returns proper class during evolve, the new class name
is not saved in ZoDB, so after next unghosting object get old class names
again.

Here is my evolve script. I really don't know what more should I do to make
Zope/ZoDB write the new class name in ZoDB. Can someone help me a bit... :)
?

def convertingClassFactory(connection, moduleName, globalName):
    #convert class name to new one and return the class object

def evolve(context):
    #dirty hack to substitute classFactory
    context.connection._reader._factory = convertingClassFactory
    root = context.connection.root().get(ZopePublication.root_name, None)
    for object in findObjectsMatching(root, lambda x: True):
        if hasattr(object, '_p_activate'):
            object._p_activate()
            object._p_changed = True
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.zope.org/pipermail/zope3-users/attachments/20070610/afe0aa67/attachment.htm


More information about the Zope3-users mailing list