Trying zodbupdate

By Maarten Kling | On Jan 22, 2010
After writing my last blog post Ross Patterson pointed me to zodbupdate. Why not give it a try and see how it works?

For this test lets create a instance having a broken contenttype. I set up a new buildout and fourdigits.testzodbupdate product having an interface, a portlet and a contenttype. Installed it, created objects and a portlet. Removed the product from my buildout, started my instance again and the instance is saying it has some broken objects. So far so good.

Time to add zodbupdate. Adding the zodbupdate package to my buildout was slightly different from what the documentation was telling. I had to add the extra-paths = ${zope2:location}/lib/python to get it working.

My buildout

parts += zodbupdate

recipe = zc.recipe.egg
eggs =     
extra-paths =

Running zodbupdate is quit easy

/opt/test/bin/zodbupdate -f /opt/test/var/filestorage/Data.fs -i

-f FILE, --file=FILE  load FileStorage
-i, --ignore-missing  update database even if classes are missing

Use the -i command so the update is fully done and you see all the errors.

My results:

Missing factory: fourdigits.testzodbupdate.content.interfaces.ITest
Missing factory: fourdigits.testzodbupdate.browser.testportlet.Assignment
Missing factory: fourdigits.testzodbupdate.contenttypes.content.testtype.testtypeclass

Time to create my new package, this one is called fourdigits.newtestproduct (very original). I created the same contenttype, portlet and interface again but all with slightly different names, to see how everything works.

Started my instance again to see if my new product is working fine, and look if im still having broken objects, again so far so good.

Time to setup rename rules for zodbupdate. First change the and add [zodbupdate] like below.

# -*- entry_points -*-

Note: this is done in my new product called fourdigits.newtestproduct. you need to set the same name after renames=

Now edit the in /fourdigits.newtestproduct/fourdigits/newtestproduct/. This is the __init__ where your probably doing: def initialize(context): etc.

Put the rename_dict at the very top of the file:

rename_dict = {
'fourdigits.testzodbupdate.content.testtype testtypeclass': \
'fourdigits.newtestproduct.content.newtype newclass',
'fourdigits.testzodbupdate.content.interfaces ITest': \
'fourdigits.newtestproduct.content.interfaces INewtest',
'fourdigits.testzodbupdate.browser.testportlet Assignment': \
'fourdigits.newtestproduct.browser.newtestportlet Assignment',

What you see here is, I have made 3 rules. First: give the old location and classname (use a space in between). Secondly: set the new location and again classname. This should be done for your contenttype, interface and portlet.

Important note here. We now have set up our rename rules. To let zodbupdate know they exist, you must run buildout again!

./bin/buildout -vN

Zodbupdate will create a list of all products found in your instance and reads the for [zodbupdate]

Now it is time to run zodbupdate again:

/opt/test/bin/zodbupdate -f /opt/test/var/filestorage/Data.fs -i

The result:

Loaded 3 rules from fourdigits.newtestproduct:renames
Committing changes.

And all is done. My first impression after starting the instance again, was that all my products where working fine again!