Hi Jim and Dieter
Thanks for the helpful answers - I'm sure you guys are right. I did
understand about _v_* attributes being volatile, but I had no idea my class
instances were being periodically stored and restored - I suppose only in
the case that they are reachable from whatever has changed during the
transaction. I'll re-think the need for those volatile attributes.
While I (hopefully) still have your attention, I have a question about
overall code design when using ZODB.
I have a top-level class (call it ABC) that I only ever want one instance
of. In __init__ of that class, it uses a couple of _v_ attributes to open a
ZODB store and get the root dictionary. If the root is empty it puts a few
things into it. It then uses setattr to set some attributes of self to
the things in the ZODB root. Then it just acts like any other Python class.
Is that normal? By "that" I mean that you just have a single class that
knows how to construct an instance from scratch, or re-populate one from a
persisted root? The alternative would seem to be some kind of helper class,
and not using the volatile attributes in ABC.__init__ to deal with pulling
in the persisted attributes.
Anyway, it works just fine, though it feels a little convoluted at times.
My concern is the following: The root contains various data structures and
variables that hold class instances, which contain others, etc etc. Many of
the class instances that are stored are created by classes that need to be
passed an instance of ABC to their __init__ and which store that instance
in their own self.abc for later use.
I.e., I have a top-level single ABC instance in a class that subclasses
Persistent, and some methods in that class pass self to the __init__ of
other classes whose instances then store the ABC reference as self.abc
As a result, when I re-start my application and say mainABC = ABC() to get
an instance of the top-level class, I can follow the data structures it
holds and get to a previously stored (in ZODB) instance of ABC (from the
last run). What I've seen is that these two ABC instances can be different
(this can be seen just by printing them and looking at their addresses) and
when a class instance that got pulled out of ZODB uses its persisted
self.abc instance, this difference becomes apparent - it is old, it doesn't
have anything newly added to the top-level ABC instance.
I hope that's making some sense.
I believe I can "solve" this by arranging for the new instance to walk its
relevant stored data in ABC.__init__, updating any stored self.abc
references to the current (just created) instance. I wrote code to do this
(putting the reference into a _v_abc attribute in the stored class
instances, which was my original error). But, maybe my setup is just plain
stupid due to lack of experience in using ZODB?
This does seem convoluted. I could also store the single top-level ABC
instance into a global variable (ugh?) - then stored class instances could
just go through that global variable to get to what they need. Or maybe
there's another way to do what I'm attempting.
If I've managed to make myself clear, does my approach sound reasonable?
If I'm not being clear, it's easy for me to whip up a small example of how
I've done things. I'd really appreciate any comments.
Thanks again for clearing up the _v_ question.
For more information about ZODB, see the ZODB Wiki:
ZODB-Dev mailing list - ZODB-Dev@zope.org