def report(oid, data, serial, missing): from_mod, from_class = get_pickle_metadata(data) if len(missing) > 1: plural = "s" else: plural = "" ts = TimeStamp(serial) print "oid %s %s.%s" % (hex(u64(oid)), from_mod, from_class) print "last updated: %s, tid=%s" % (ts, hex(u64(serial))) print "refers to object%s:" % plural for oid, info, reason in missing: if isinstance(info, types.TupleType): description = "%s.%s" % info else: description = str(info) print "\toid %s %s: %r" % (oid_repr(oid), reason, description) print
def iterate_counts_sizes(path): """Count and display the number and total size of every class of objects. NOTE: For accurate results, run on a packed db -- otherwise, objects will be counted multiple times. """ from ZODB.FileStorage import FileIterator from ZODB.FileStorage.fsdump import get_pickle_metadata counts = {} sizes = {} fiter = FileIterator(path) for trans in fiter: for rec in trans: if rec.data: modname, classname = get_pickle_metadata(rec.data) counts[classname] = counts.get(classname, 0) + 1 sizes[classname] = sizes.get(classname, 0) + len(rec.data) bycount = [] for classname, c in counts.iteritems(): bycount.append((c, classname)) del counts bycount.sort() bycount.reverse() bysize = [] for classname, s in sizes.iteritems(): bysize.append((s, classname)) bysize.sort() bysize.reverse() print "By object count" for c, name in bycount: print '%10d %s' % (c, name) print '\n\nBy size' for s, name in bysize: print '%10d %s' % (s, name)