Move a Python module from one Zope Product to another
Last December I started on a another refactoring of our company's Zope Application. This time I was going to split out some of the stuff into separate Products, so I could install them only when needed. All nice and clean, but the instances of those classes / products in the ZODB didn't like their code to be moved out from under their feet. I asked around on #zope and TresEquis showed me what to do. Since this stuff is kind of hard to find, here is a little writeup.
Basically what we are doing is to place a snippet of code into the __init__.py of the new location, then remove the registerClass() calls from the __init__.py of the old location. That snippet says something like "I'm now responsible for these modules formerly found there." Lot's of talk, here is what it looks like:
__module_aliases__ = (
( 'Products.OldProd.mod1',
'Products.NewProd.mod1' ),
( 'Products.OldProd.mod2',
'Products.NewProd.mod2' ),
)
In our example this would be placed in the __init__.py of NewProd.
As Simon noticed, you can use a list of tuples too. If you want to move the modules around in the same Zope Product, that will work too: Fix the import lines, declare __module_aliases__, all in the same __init__.py.
Tres offered some more hints on this thing, basically he wrote:
[This] creates aliases to the old names in sys.modules. You probably want to use them to support a content migration or at least touch and store all content.
So far in my experience it has worked fine, but I don't know about the longevity and trustworthyness. of this solution. Myself I will follow Tres advice and have every instance touched and re-stored in the ZODB at some point (lots of disk thrashing involved).