[ZODB-Dev] question

Shane Hathaway shane at zope.com
Wed Sep 10 16:02:42 EDT 2003


Christian Reis wrote:
> On Wed, Sep 10, 2003 at 02:12:10PM -0400, Shane Hathaway wrote:
>>Use a trivial deep copy.  (Although copy.deepcopy() doesn't like 
>>ExtensionClass, so if you're using ZODB 3.2 or below, you need to use 
>>cPickle to make the deep copy.  I can show you how if you're need it.)
> 
> 
> Please do, that's something I've often wondered about.

Here is the simplest version:


import cPickle

def deepcopy(obj):
     return cPickle.loads(cPickle.dumps(obj))


This will ignore ZODB record boundaries and make a copy of the whole 
subtree.  The copy will have its _p_jar and _p_oid attributes unset.  It 
will be disconnected entirely from the database until you store it.

Unfortunately, I'm pretty sure it's naive with ghosts (it may pickle 
ghosts as objects with no attributes) and it fails for ZClasses.  So a 
fully-elaborated version of the above is in the Ape product. 
Unfortunately, it's far more complex, but fortunately, it's known to work.

http://cvs.zope.org/Products/Ape/lib/apelib/zodb3/utils.py?rev=1.1&content-type=text/vnd.viewcvs-markup

>>Splitting up transactions would open major holes.  You'd need something 
>>quite unlike ZODB to get it right.  Making temporary copies is much 
>>simpler.
> 
> 
> Okay, okay -- if only because you said so ;-)

Oh man, don't let me put down your idea.  I like it, but it's hard to 
generalize to all ZODB users.  So now I'll switch to your side for a moment.

I'll let you in on a secret: previously, the transaction was directly 
notified of every object change, but today, the _p_jar gets the 
notification instead through its register() method.  The standard _p_jar 
(a Connection object) always passes the notification to the transaction, 
but you could make a subclass of Connection that does something 
different.  For example, you could collect the notifications in a group 
and choose to commit them separately.

By subclassing Connection and overriding the register() method, you can 
try out your idea without changing ZODB.  You might get into crazy 
situations if some object gets modified by multiple groups, or by a 
group as well as the transaction, but you can structure your application 
in such a way to prevent that from happening.

I've overridden register() a few times for my own nefarious purposes and 
it works like magic.  It gives you a whole new insight into ZODB.

Shane




More information about the ZODB-Dev mailing list