[ZODB-Dev] Coping with Class Changes

Syver Enstad syver at inout.no
Wed Sep 6 07:33:30 EDT 2006


Dieter Maurer skrev:
> Chris S wrote at 2006-9-3 15:40 -0400:
>> Is there a standard procedure for dealing with fundamental changes to
>> classes? For instance, how do you make a ZODB cope with a class being
>> renamed, or being placed in a different location? How will it know
>> that oldmod.myclass == newmod.myclass?
> 
> It does not.
> 
> You can use so called "module aliases" to partially cope
> with module relocation and "class aliases" to cope with class renaming.
> Otherwise, you have to use migration scripts that physically
> recreate the objects (and the references to it!) with the new classes.
> 

It does too! :-) (In a fashion)

You implement your own classFactory method and set that to be the DB 
instance's classFactory.

If you then load all the objects in the database, you can map 
modulename, globalname to the new location and return the correct 
classes. If you also mark every object as changed and then commit the 
transaction all the invalid modulename, globalnames are updated to the 
new location in your source.

ex sketch:
In migration script

from ZODB.broken import find_global, Broken

def myClassFactory(connection, modulename, globalname):
     # simplified, without error checking
     theGlobal = find_global(modulename, globalname)
     if issubclass(theGlobal, Broken):
	newModulename, newGlobalname = translateLocation(modulename, 	globalname)
	theGlobal = find_global(newModulename, newGlobalname)
     return theGlobal

def translateLocation(modulename, globalname):
     # perhaps have a dictionary mapping tuples of old modulename, 
globalname to a tuple of new modulename, globalname.
     # a version integer in the root can help performing the correct 
mappings in case you've done a back and forth rename and want to support 
converting databases from several different version.
	

db = DB(someStorage)
db.classFactory = myClassFactory
conn = db.open()
for each in ZodbIterator(conn)
     each._p_activate()
     each._p_changed = True
transaction.commit()

The ZodbIterator class is something I stole from someone and modified a bit.



More information about the ZODB-Dev mailing list