[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