Skip to content

Instantly share code, notes, and snippets.

@icemac icemac/ forked from buchi/
Last active Jan 10, 2020

What would you like to do?
ZODB: find oids of objects referencing a specific oid
First create a refmap of your ZODB:
>>> r = buid_refmap('/path/to/Data.fs')
Now you can find out which objects reference an object you know the oid of:
>>> oid = '\x00\x00\x00\x00\x00uB\xf1'
>>> backrefs(oid, r)
To find out the object behind the gotten oid, get it from the ZODB:
>>> import ZODB
>>> db ='/path/to/Data.fs')
>>> c =
>>> obj = c.get('\x00\x00\x00\x00\x00uC\x1f')
To load a pure pickle from the storage use:
>>> fs = FileStorage('/path/to/Data.fs', read_only=1)
>>> fs.load('\x00\x00\x00\x00\x00uC\x1f')
from ZODB.serialize import referencesf
from ZODB.FileStorage import FileStorage
def build_refmap(filename):
"""Build a refmap from a filestorage. Look in every record of every
transaction. Build a dict of oid -> list(referenced oids)
refmap = {}
fs = FileStorage(filename, read_only=1)
fsi = fs.iterator()
for txn in fsi:
for rec in txn:
pickle, revid = fs.load(rec.oid, rec.version)
refs = referencesf(pickle)
refmap[rec.oid] = refs
return refmap
def backrefs(target, refmap):
"""Return a list of oids in the refmap who reference target.
oidlist = []
for oid, refs in refmap.items():
if target in refs:
return oidlist
def obj_path(target, refmap):
"""For a target oid find the path of objects that refer to it.
break if we reach no more references or find a cycle
path = [target]
additionals = []
while True:
target = path[-1:].pop()
brefs = backrefs(target, refmap)
if not brefs:
bref = brefs[0]
if bref in path:
print('cyclic', bref)
if len(brefs) == 1:
additionals.append((target, brefs[1:]))
print(bref, brefs[1:])
return (path, additionals)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.