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.
 

Trying zodbupdate

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

[buildout]
parts += zodbupdate

[zodbupdate]
recipe = zc.recipe.egg
eggs =     
${instance:eggs}
extra-paths =
${zope2:location}/lib/python

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 setup.py and add [zodbupdate] like below.

entry_points="""
# -*- entry_points -*-
[zodbupdate]
renames=fourdigits.newtestproduct:rename_dict

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

Now edit the __init__.py 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 setup.py 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!

 
Enrique Pérez

Changing the __class__ attribute

Posted by Enrique Pérez at Jan 26, 2010 03:36 PM
Hi Maarten.

In a similar situation, we've taken the approach you described in your previous post (Changing your packagename), of changing the __class__ attribute by hand. I would be grateful if you can elaborate a little on the reasons for changing the approach to use zodbupdate, i.e., did you encounter problems that forced you to change the approach? What advantages have you gained?

Thanks
 
Maarten Kling

Changing the __class__ attribute

Posted by Maarten Kling at Jan 26, 2010 03:49 PM
There where no problems using my first approach, just did not know about zodbupate and I'm always interested in new things so i tried it this way.

I think one advantage for using zodbupdate you can create your new package using the setup.py and __init__ rules and role out your product, leaving the change code inside your product. The first way you need to create a debug.py or something and you had to delete it after use.
One more thing using: zodbupdate -i will tell you what products are missing, like missing portlets, interfaces, etc. In my first way i had to find out myself :)

Hope this post worked out for you. ~
 
Made by Four Digits based on Plone.
Made by Four Digits based on Plone.