This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author gregory.p.smith
Recipients
Date 2005-06-05.02:18:17
SpamBayes Score
Marked as misclassified
Message-id
In-reply-to
Content
To: Michael C Urban <murban@cbs.umn.edu>
Cc: pybsddb-users@lists.sourceforge.net
Date: Sat, 4 Jun 2005 18:21:34 -0700


On Sat, Jun 04, 2005 at 06:16:37PM -0500, Michael C
Urban wrote:
> Hi all,
>
> I'm running into a TypeError when I try to associate
a secondary db with a
> primary one. But the error only occurs when I use an
object oriented
> style, so I am wondering it it might be a bug.
>
> Basically, the following works fine:
>
> db = DB(None, 0)
> db.open("testDb.db", None, DB_BTREE, DB_CREATE, 0660)
> dbs = DB(None, 0)
> dbs.open("testDbS.db", None, DB_BTREE, DB_CREATE, 0660)
> db.associate(dbs, makeAddressKey, 0)
>
> However, the following similar code does not:
>
> def __dbInitialize(self, dbDir, fileName):
>    self.__dbEnv = dbobj.DBEnv(0)
>    self.__dbEnv.open(dbDir, db.DB_INIT_TXN |
db.DB_CREATE |
>           db.DB_INIT_MPOOL)
>
>    self.__dbMain = dbobj.DB(self.__dbEnv, 0)
>    self.__nameIdx = dbobj.DB(self.__dbEnv, 0)
>
>    self.__dbMain.open(fileName, None, db.DB_BTREE,
db.DB_CREATE, 0660)
>    self.__nameIdx.open("nameDb.idx", None, db.DB_BTREE,
>           db.DB_CREATE, 0660)
>
>    self.__dbMain.associate(self.__nameIdx,
self.__makeNameKey, 0)
>
> ...
> The last line causes the following error:
>
> TypeError: Expected DB argument, instance found.
>
> Am I doing something wrong here? The only difference
I can see between the
> first example and the second one is that one uses a
private variable from
> the class, and the other does not use object oriented
style. The databases
> all get created fine, as to the log files. It's only
when I try to
> associate that I have the problem.
>
> Thanks for any help in advance.

This is happening because the C wrapper requires that
the secondaryDB
parameter to associate() is a C wrapper DB object.

My first suggestion is based on the code above, use
db.DB not
dbobj.DB.  dbobj is only a wrapper around the C db.DB
to allow people
to subclass it.

If you do need to use a dbobj derived class for the
secondary DB,
realize that BerkeleyDB doesn't call back to python for
DB access so
it won't use any overridden methods.  If thats ok, then
add the
following overridden method to your dbobj derived class
and associate
should work:

<pre>
    def associate(self, *args, **kwargs):
        # if we're given a dbobj derived secondaryDB we
need to pass
        # the actual C db.DB object to BerkeleyDB.  do it.
        argDB = kwargs.get('secondaryDB')
        if not argDB:
            argDB = args.pop(0)
        if isinstance(argDB, DB):
            kwargs['secondaryDB'] = argDB._cobj
        return apply(self._cobj.associate, args, kwargs)
</pre>

This passes the internal C db.DB object to the
BerkeleyDB associate method.

I'm pasting this email as a pybsddb bug report.  the
above method should probably be used as the base
dbobj.associate.
History
Date User Action Args
2007-08-23 14:32:19adminlinkissue1215023 messages
2007-08-23 14:32:19admincreate