Since your exception is happening during __del__ and since AFAIK no guarantees are made as to what will exist is sys.modules during any given object's __del__, it's maybe not suprising that you're getting this exception. I don't know that this has anything to do with ZODB in particular.

The first thing I'd try to do is to move the cleanup code out of __del__ (and perhaps to a finally: after the line that creates the cache instead) and see if that helps.

- C

On Jul 29, 2006, at 9:40 AM, [EMAIL PROTECTED] wrote:


Matt Cowles has a DNS cache module with a patch for use with SpamBayes. It doesn't persist the data (just caches during the lifetime of the run). I'm trying to add persistence to that cache and wanting to use the same database as the user selects for the main SpamBayes database, my first two targets were anydbm and ZODB. I'm having trouble with the ZODB setup. It seemed to work well at the start, but the database file is never updated when I rerun my training script, so its not caching anything, and now everything in the database has expired. I've never used ZODB before. The amount of code is fairly small, so I'll just post it here in hopes someone can see what I've
done wrong.

When opening the database it selects based on the user-preferred filetype.
For "zodb" it executes:

    from ZODB import DB
    from ZODB.FileStorage import FileStorage
    self._zodb_storage = FileStorage(cachefile, read_only=False)
    self._DB = DB(self._zodb_storage, cache_size=10000)
    self._conn = self._DB.open()
    root = self._conn.root()
    self.caches = root.get("dnscache")
    if self.caches is None:
        # There is no classifier, so create one.
        from BTrees.OOBTree import OOBTree
        self.caches = root["dnscache"] = OOBTree()
        self.caches["A"] = {}
        self.caches["PTR"] = {}

That gives the cache a caches attribute that looks like the dictionary it
uses in the no persistence case.

When the cache is deleted, its __del__ method calls

    self.close()

which calls self._zodb_close():

  def _zodb_close(self):
      # Ensure that the db is saved before closing.  Alternatively, we
# could abort any waiting transaction. We need to do *something*
      # with it, though, or it will be still around after the db is
# closed and cause problems. For now, saving seems to make sense
      # (and we can always add abort methods if they are ever needed).
      self._zodb_store()

      # Do the closing.
      self._DB.close()

which calls self._zodb_store():

  def _zodb_store(self):
      import transaction
      from ZODB.POSException import ConflictError
      from ZODB.POSException import TransactionFailedError

      try:
          transaction.commit()
      except ConflictError, msg:
          # We'll save it next time, or on close.  It'll be lost if we
# hard-crash, but that's unlikely, and not a particularly big
          # deal.
          if options["globals", "verbose"]:
              print >> sys.stderr, "Conflict on commit.", msg
          transaction.abort()
      except TransactionFailedError, msg:
          # Saving isn't working.  Try to abort, but chances are that
          # restarting is needed.
          if options["globals", "verbose"]:
print >> sys.stderr, "Store failed. Need to restart.", msg
          transaction.abort()

which seems to fail.  I get this message in the log:

    Exception exceptions.ImportError: 'No module named transaction' in
<bound method cache.__del__ of <spambayes.dnscache.cache instance at
    0x11994b8>> ignored

I can import transaction from the interpreter prompt just fine:

    % python
    Python 2.5b2 (trunk:50921, Jul 28 2006, 20:21:50)
    [GCC 4.0.0 (Apple Computer, Inc. build 5026)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
import transaction
transaction.__file__
'/Users/skip/local/lib/python2.5/site-packages/transaction/ __init__.pyc'
import ZODB
ZODB.__file__
    '/Users/skip/local/lib/python2.5/site-packages/ZODB/__init__.pyc'

I stuck a

    print transaction.__file__

after the import in _zodb_close and ran dnscache as a main. It prints out

/Users/skip/local/lib/python2.5/site-packages/transaction/ __init__.pyc

so I'm pretty sure I'm getting the same version of Python. Any idea why it would fail in one instance but not another? The only thing I can think of is that there are two ZODB databases opened at the same time in the real use case, but only the one in the situation where I'm running the dnscache test function. Is there something about having two distinct ZODB database files
open I need to consider?

Thanks,

--
Skip Montanaro - [EMAIL PROTECTED] - http://www.mojam.com/
_______________________________________________
For more information about ZODB, see the ZODB Wiki:
http://www.zope.org/Wikis/ZODB/

ZODB-Dev mailing list  -  ZODB-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zodb-dev


_______________________________________________
For more information about ZODB, see the ZODB Wiki:
http://www.zope.org/Wikis/ZODB/

ZODB-Dev mailing list  -  ZODB-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zodb-dev

Reply via email to