On Wed, Mar 02, 2005 at 12:05:32PM -0500, A.M. Kuchling wrote: > the export may collide with OIDs used by the current database. It > seems to me that a function similar to copy_object() would still be > required. Iteration 2: copy_obj() takes an object and cleans off the .._p_connection and ._p_oid attributes. The resulting object, untied to any particular connection, can be placed in a different Durus database. export_object(obj, filename, key) opens the storage 'filename' and records a copy of the object in the root object using 'key'. import_object(filename, key) opens the storage and returns a cleaned copy of the object stored under 'key'. This interface lets you export multiple objects into a single storage. (The 'cleaned' terminology isn't particularly descriptive of breaking the link between an object and its storage; any better suggestions? "Checked out"? "Divorced"?) --amk import os from ACE_model import get_model, get_connection m = get_model('small') print m from durus import serialize, connection, file_storage def copy_obj (obj): """Copies the object 'obj', cleaning it and all required objects of the attributes tying it to a particular Durus connection. """ conn = obj._p_connection if conn is None: # Returning the existing object is convenient; will it hide errors, though? return obj ##raise RuntimeError("Object %r is not stored in Durus database") ow = serialize.ObjectWriter(conn) root_oid = obj._p_oid queue = [root_oid] oid_coll = {} while len(queue): oid = queue.pop(0) if oid in oid_coll: continue # Get object for this OID obj = conn.get(oid) if obj is None: ##print 'no object with oid', repr(oid) continue oid_coll[oid] = obj # Ensure object is loaded if obj._p_is_ghost(): conn.load_state(obj) # Get OIDs referenced by this object and add them to the queue data, refs = ow.get_state(obj) refs = serialize.split_oids(refs) queue.extend(refs) # Need to put this in a try/finally w/ preceding block ow.close() print len(oid_coll), 'objects' # Clear _p_ attributes for obj in oid_coll.values(): obj._p_oid = obj._p_connection = None return oid_coll[root_oid] def export_object (obj, filename, key): """Write the specified object to the given storage, using the given 'key' within the root object.""" fs = file_storage.FileStorage(filename) conn2 = connection.Connection(fs) root = conn2.get_root() copy = copy_obj(obj) root[key] = copy conn2.commit() del conn2 fs.close() def import_object (filename, key): """Return a copy of the object from the specified storage.""" fs = file_storage.FileStorage(filename, readonly=True) conn2 = connection.Connection(fs) root = conn2.get_root() obj = root[key] result = copy_obj(obj) del conn2 fs.close() return result filename = '/tmp/new-fs' if os.path.exists(filename): os.remove(filename) export_object(m, filename, 'model') m2 = import_object(filename, 'model') m3 = copy_obj(m2) m3.dump()