The main reason I use Shelve is to be able to quickly develop code without worrying about db table structure. Unfortunately changing a class name from, say, 'class1' to 'class2' gives "AttributeError: 'module' object has no attribute 'class2'" on the next run. What is the canonical way to rename a Shelved class? What other similar surprises are lurking deeper into the Shelve db structure?
1 Answer
Shelve uses pickle to serialize objects. Pickle loads objects by name; the module and class name are stored and looked up when deserialising.
The easiest way to support 'legacy' names is to simply create an alias:
class NewName(object):
# a renamed object, once named OldName
# backwards-compatible names for unpickling
OldName = NewName
When unpickling, modulename.OldName is looked up and used, which is simply the same class as NewName. When storing a change in the shelve, the new name will be used.
-
Ok, seems to work with my simple data structures. In general, then, one would need 1) an OldName = NewName statement for each object renamed, and 2) a one time read + write of all objects, and 3) deleting all OldName = NewName. I'll do some experimenting.Mayavimmer– Mayavimmer2014-05-05 16:52:36 +00:00Commented May 5, 2014 at 16:52
-
@Mayavimmer: you can include the 'alias' in the code that does the shelve refresh; e.g. load everything, save everything again in a script, but include a
import mymodule; mymodule.OldName = mymodule.NewNameline to inject the alias just for the migration.Martijn Pieters– Martijn Pieters2014-05-05 16:54:32 +00:00Commented May 5, 2014 at 16:54