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.

classification
Title: bsddb dbobj.DB.associate doesn't accept dbobj.DB param
Type: Stage:
Components: Extension Modules Versions:
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: gregory.p.smith Nosy List: gregory.p.smith, jcea
Priority: low Keywords:

Created on 2005-06-05 02:18 by gregory.p.smith, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (2)
msg25489 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2005-06-05 02:18
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.
msg66982 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2008-05-17 07:04
I think the workaround proposed in my email in this bug is sufficient. 
Blindly letting associate work on python wrapped overridden objects such
that the underlying library doesn't call into the wrapper could confuse
people.
History
Date User Action Args
2022-04-11 14:56:11adminsetgithub: 42055
2008-05-17 07:04:40gregory.p.smithsetstatus: open -> closed
resolution: wont fix
messages: + msg66982
2008-03-10 18:28:48jceasetnosy: + jcea
2005-06-05 02:18:17gregory.p.smithcreate