<br><div><span class="gmail_quote">On 6/8/07, <b class="gmail_sendername">Alek Kowalczyk</b> <<a href="mailto:thealx@poczta.onet.pl">thealx@poczta.onet.pl</a>> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Alek Kowalczyk <thealx@...> writes:<br><br>><br>> Hi,<br>> I moved my content class from mypackage.mymodule.MyContentClass into<br>> mypackage.mysubpackage.mymodule.MyContentClass.<br>> But when started Zope and went to visit an object I have previously created (of
<br>> MyContentClass), I get:<br>> ComponentLookupError: ((<persistent broken mypackage.mymodule.MyContentClass<br>> instance '\x00\x00\x00\x00\x00\x00\x02q'>,<br>> <zope.publisher.browser.BrowserRequest
instance <br></blockquote><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">I found a quite well working solution on<br><a href="http://mail.zope.org/pipermail/zodb-dev/2006-September/010382.html">
http://mail.zope.org/pipermail/zodb-dev/2006-September/010382.html</a><br><br>There was only one issue: this solution assumes that we have given a DB, while<br>Zope evolve method receives already open connection. Unfortunately classFactory
<br>from DB is cached in Connection's private fields in constructor.<br>Because of that I could not assign my custom 'renaming' class factory using:<br><br>def evolve(context): #won't work!<br> context.connection.db
().classFactory = myClassFactory<br><br>Instead I had to do some dirty private fields substitution in Connection's<br>ObjectReader:<br><br>def evolve(context): #this works nice<br> context.connection._reader._factory
= myClassFactory</blockquote><div><br>I shouldn't announce success too early. The solution works but only during first Zope run (i.e just after evolving the schema). <br>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.
<br><br></div>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... :) ?<br><br>def convertingClassFactory(connection, moduleName, globalName):
<br> #convert class name to new one and return the class object<br><br>def evolve(context):<br> #dirty hack to substitute classFactory<br> context.connection._reader._factory = convertingClassFactory<br> root =
context.connection.root().get(ZopePublication.root_name, None)<br> for object in findObjectsMatching(root, lambda x: True):<br> if hasattr(object, '_p_activate'):<br> object._p_activate()<br> object._p_changed = True
<br><br></div>