Aleksander Kowalczyk wrote: > On 6/8/07, Alek Kowalczyk <[EMAIL PROTECTED]> wrote: >> >> Alek Kowalczyk <[EMAIL PROTECTED]> 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 >
Somebody correct me if I'm wrong I imagine you'd need to commit the transaction manually: 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 import transaction transaction.commit() Hope that helps, Rupert _______________________________________________ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users