Commit cac01bae authored by Jim Fulton's avatar Jim Fulton

Added logic to handle missing modules needed to unpickle data objects

during converesion. We now skip affected records and output error
messages.
parent 164c80ad
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
############################################################################## ##############################################################################
"""Nitty-gritty conversion of a ZODB 4 FileStorage to a ZODB 3 FileStorage.""" """Nitty-gritty conversion of a ZODB 4 FileStorage to a ZODB 3 FileStorage."""
import sys
from cPickle import dumps, Pickler, Unpickler from cPickle import dumps, Pickler, Unpickler
from cStringIO import StringIO from cStringIO import StringIO
...@@ -56,6 +57,8 @@ class DataRecordConvertingTxn(object): ...@@ -56,6 +57,8 @@ class DataRecordConvertingTxn(object):
return getattr(self._txn, name) return getattr(self._txn, name)
def __iter__(self): def __iter__(self):
errors = {}
skipped = 0
for record in self._txn: for record in self._txn:
record.tid = record.serial record.tid = record.serial
# transform the data record format # transform the data record format
...@@ -63,8 +66,20 @@ class DataRecordConvertingTxn(object): ...@@ -63,8 +66,20 @@ class DataRecordConvertingTxn(object):
sio = StringIO(record.data) sio = StringIO(record.data)
up = Unpickler(sio) up = Unpickler(sio)
up.persistent_load = PersistentIdentifier up.persistent_load = PersistentIdentifier
classmeta = up.load() try:
state = up.load() classmeta = up.load()
state = up.load()
except ImportError, v:
v = str(v)
if v not in errors:
if not errors:
sys.stderr.write("Pickling import errors:\n")
sys.stderr.write('\t'+v+'\n')
errors[v] = True
skipped += 1
continue
sio = StringIO() sio = StringIO()
p = Pickler(sio, 1) p = Pickler(sio, 1)
p.persistent_id = get_persistent_id p.persistent_id = get_persistent_id
...@@ -73,6 +88,23 @@ class DataRecordConvertingTxn(object): ...@@ -73,6 +88,23 @@ class DataRecordConvertingTxn(object):
record.data = sio.getvalue() record.data = sio.getvalue()
yield record yield record
if errors:
sys.stderr.write(error_explanation)
sys.stderr.write("%s database records skipped\n" % skipped)
error_explanation = """
There were import errors while copying data records.
This is because modules referenced by the database couldn't be found.
You might be able to fix this by getting the necessary modules.
It's possible that the affected objects aren't used any more,
in which case, it doesn't matter whether they were copied.
(We apologise for the lame import errors that don't show full dotted
module names.)
"""
class PersistentIdentifier: class PersistentIdentifier:
def __init__(self, ident): def __init__(self, ident):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment