[ZODB-Dev] Persistent unhashable?

JohnD.Heintz JohnD.Heintz
Tue, 3 Jul 2001 22:54:13 -0500


Hi Greg,

I too have faced this problem.  I don't remember when the discussion was =
or=20
with whom (see ZODB-Dev archives?) but this is what I learned:

The __hash__ method you've coded below is dangerous because the hash code=
 for=20
an object should never change.  At a minimum changing the hash code means=
=20
that you lose the performance gained by hashing in the first place becaus=
e=20
the Python dictionary implementation falls back onto a linear search.

Instead of the else: clause below return id(self) it should raise a=20
HashableError (name?).

Now comes the wisdom I learned: In order to get a _p_oid for just created=
=20
objects you can make sure that they are refered to by an already persiste=
d=20
object and then get_transaction().commit(1) to commit a sub-transaction. =
=20
This will have the side effect of generating persistent ids for all objec=
ts=20
reachable from the root.

Hope this helps.

John

PS - Our persistent base class uses a __hash__ function like this to make=
 the=20
process more convenient:
def __hash__(self):
=09if not self._p_oid:
=09=09some.global.ensurePid(self)
=09return hash(self._p_oid)

Our some.global.ensurePid function relies on the current thread to get th=
e=20
current transaction and current database/connection. =20


On Tuesday 03 July 2001 19:03, Greg Ward wrote:
> On 03 July 2001, Christian Robottom Reis said:
> > I'm trying to create a simple hash of persistent objects to other
> > persistent object. Something like:
>
> [...]
>
> > raises an AttributeError: __hash__ error! Why?
> >
> > Is this a known limitation of Persistent?
>
> It's been known to me for a while.  I finally got around to "fixing" it
> for our project by adding this method:
>
>     def __hash__ (self):
>         if self._p_oid:
>             return hash(self._p_oid)
>         else:
>             return id(self)
>
> to our standard persistent base class.  (Rather than having all of our
> database classes derive directly from Persistent, we use an intermediar=
y
> class, precisely to allow this sort of customization.  Phew, that was a
> lucky design choice!)
>
> Is there any reason Persistent doesn't do this for us automatically?  O=
r
> was it just an oversight?
>
>         Greg

--=20
=2E . . . . . . . . . . . . . . . . . . . . . . .

John D. Heintz | Senior Engineer

1016 La Posada Dr. | Suite 240 | Austin TX 78752
T 512.633.1198 | jheintz@isogen.com

w w w . d a t a c h a n n e l . c o m