[ZODB-Dev] [Fixed?] _p_jar magic stopped working

Ross Boylan RossBoylan@stanfordalumni.org
Fri, 9 Aug 2002 12:10:35 -0700


I think I've fixed this.  Can anyone confirm my new approach is good?

The big problem was that the db no longer provides dictionary-like
semantics for named objects.  Instead I use _p_jar.root() to get what
I hope is the same thing.

The smaller problem with my old code was that db stopped being an
instance variable and became a method.  So _p_jar.db() gets the db.
It was at that point I discovered I didn't want the db any more.

Looking in the change logs it appears the last big db change was at
Zope 2.0, and I thought my earlier work postdated that.  Have there
been more recent changes, or have I just been away longer than I
thought?


Here's the new code:
def getMasterFor(object, edressList=None):
    "Return master <EMailList> relative to argument"
    # argument must be persistent
    # WARNING: Low level implementation dependency
    print "People.getMasterFor"
    db = object._p_jar.root()  #db is only db-like!
    master = db.get(_masterName)
    if master == None:
        print "Didn't find", _masterName
        if edressList == None:
            edressList = EdressList.getMasterFor(object)
        master = People(edressList)
        db[_masterName] = master
    return master

P.S. The docs say _p_jar is None if the object has not been saved, but
it appears to be a valid Connection even with the object created in
the same transaction.  From
http://www.zope.org/Documentation/Developer/Models/ZODB:

ZODB.Persistent Objects.Persistent._p_jar
Documentation
The object?s Connection. If the object has not been saved, then this is None.

At any rate, I changed to using a previously saved object to be safe,
but this wasn't the problem.

On Tue, Aug 06, 2002 at 05:12:29PM -0700, Ross Boylan wrote:
> Awhile ago someone (I think Jim Fulton--thanks again) gave me a little
> trick pull a globally accessible object out of the db, as used in the
> following code: 
> 
> _masterName = "People-Master"
> 
> def getMasterFor(object, edressList=None):
>     "Return master <EMailList> relative to argument"
>     # argument must be persistent
>     # WARNING: Low level implementation dependency
>     db = object._p_jar.db
>     print type(db), dir(db)
>     master = db.get(_masterName)
>     if master == None:
>         if edressList == None:
>             edressList = EdressList.getMasterFor(object)
>         master = People(edressList)
>         db[_masterName] = master
>     return master
> 
> object is just any random persistent object so I can get a handle to
> the db.
> 
> When I try this in Zope 2.5.1, it fails on the db.get, with 
> Error Type: AttributeError
> Error Value: get
> 
> Further, the debugging code above shows that db is now of type
> 'instance method', which is not exactly what I was aiming for!
> 
> Can anyone tell me what's changed and what I need to do?
> 
> Hmm, in this case object was created earlier in the same
> transaction--could that be the trouble?
> 
> My apologies if this is the wrong list; the description says it's all
> about ZODB, though the title sort of implies it's only for development
> of same.  The question seemed better here than the general list.
> 
> To explain what I'm trying to do substantively: I want to use the same
> db/connection/ etc that Zope is using, and stuff an object in a well
> known key.
> 
> This is motivated by two concerns: first, I really want the data to be
> global.  Second, I may eventually want it to be accessible by
> processes running outside of Zope (e.g., a mail handler)--though I
> believe I would need to go to ZEO for multiple processes to access the
> db.  If you have any wisdom on that, I'd love to hear it too.
> 
> Thanks.
>