Skip to content. | Skip to navigation

Four Digits | Willemsplein 44, 6811 KD Arnhem, The Netherlands | info@fourdigits.nl
 
Maarten Kling is working as a Senior developer for Four Digits in the Netherlands. Maarten is a Zope developer for seven years and a Plone developer and integrator for four years. Maarten has implemented over a dozen websites, some examples are; Cool Region, NPO and the Royal Dutch Chess Organisation. His specialisation is implementing a website design in Plone based on a Photoshop document and creating viewlets, portlets and content-types.
 

Changing your packagename

One day you think lets clean up my code and rename all my products to something useful

Use Plone for several years and you will always find some product you made years ago and still frequently use today.

Now I recently had such a product, it was called Products.MyClientAdres. The name was reffering to some client but had nothing to do with it anymore. It was used in a completley different site but still used the same old svn location and package name.

My new package

When decided to change the name, I just blindly copied the product, renamed all the MyClientAdres things to my new package name 'fourdigits.organisations' and put everything in my buildout.

The result was very easy to predict, all my objects where broken after deleting the old product from the instance. They where all looking for Products.MyClientAdres.content.organisations but that was gone.

Convert the objects

To get my products back alive we need to change the __class__ of every object we made with the old product. First thing to keep in mind, keep both you old and new product installed in your instance because you cannot call a broken object!

Make a script to convert all the __class__ to you new class. Get the new class name from you package, here its called Adressenbank and Organisatie.

from fourdigits.organisations.content.Adressenbank import Adressenbank
from fourdigits.organisations.content.Organisatie import Organisatie

Convert the old adressenbank folder to the new Adressenbank contenttype from my new package.

adressenbank = getSite().unrestrictedTraverse('adressenbank')
tmp = Adressenbank(self.context)
adressenbank.__class__ =  tmp.__class__

Convert the +3000 organisations still in the folder above.


ct = getToolByName(self, 'portal_catalog')
query = {}
query['object_provides'] = 'Products.MyClientAdres.content.interfaces.IOrganisatie'
results = ct(query)
tmp = Organisatie(self.context)

for result in results:
obj = result.getObject()
obj.__class__ =  tmp.__class__

transaction.commit()

Rebuild the catalog by hand after your finished running the script.

Restart you instance and use quickingstaller to uninstalled your old product. Restart again and smile, all your object are working using your new product.

~

 
Ross Patterson

zodbupdate

Posted by Ross Patterson at Dec 18, 2009 10:07 PM
I prefer to use zodbupdate:

http://pypi.python.org/pypi/zodbupdate

Also, I don't think changing the __class__ attr is relevant other than making the ZODB machinery recognize that the object has been changed same as if you'd done "obj._p_changed = True". __class__ attributes are references to the class object which is the same object regardless of where it's imported from. I believe the ZODB gets the correct path for the __class__ object using the __class__.__module__ attribute. I think this is what zodbupdate does, walks the ZODB object graph looking for ZODB pickles whose __class__ path doesn't match the path of the real object as determined by it's __class__.__module__ and then simply marks those objects as "obj.p_changed = True".
 
Martijn Jacobs

zodbupdate

Posted by Martijn Jacobs at Dec 20, 2009 02:24 PM
We were not aware of this package, and it looks like a very nice solution. Changing the __class__ attribute worked with trial and error, and we needed a solution for this quickly, so that is why we went for this solution. Thanks for the comments, at least we know a little bit more of how the ZODB works on this matter :)
 
Made by Four Digits based on Plone.
Made by Four Digits based on Plone.