[PEAK] Recursive __setstate__ call

Radek Kanovsky rk at dat.cz
Thu Mar 25 11:30:11 EST 2004


Hi all,

there is probably something wrong with storage.DM or model.Element.
I have traced SQL queries in my application and noticed that `_load'
method is called many time twice at one point. Bellow is minimal example
that does the same. I don't know yet what's wrong but origin is in
recursive call of setstate method of EntityDM. The effect would be seen
if `raise ...' command in _load method is uncommented.

    from peak.api import *

    class User(model.Element):
        class uid (model.Attribute):
            referencedType = model.Integer
        class login (model.Attribute):
            referencedType = model.String

    class UserDM(storage.EntityDM):
        db           = binding.Obtain("pgsql://me:mypwd@localhost/test")
        defaultClass = User
        def _load(self, oid, ob):
            #raise Exception(oid)
            row = ~self.db('SELECT * FROM "user" WHERE uid=%s' % oid)
            return self.stateFromRow(row)
        def stateFromRow(self,row):
            return {"uid":row.uid, "login":row.login}
        def _save(self, ob):
            self.db("""UPDATE "user" SET uid=%d, login='%s' WHERE oid=%d""" % (
                       ob.uid, ob.login, ob._p_oid))

    dm = UserDM(config.makeRoot())

    storage.begin(dm)
    user = dm[1]
    user.login = "hello"
    storage.commit(dm)



Here is traceback seen from _load method that shows setstate
recursive call:

    Traceback (most recent call last):
      File "./userDM.py", line 28, in ?
        user.login = "hello"
      File "site-packages/peak/storage/data_managers.py", line 318, in setstate
        ob.__setstate__(self._load(oid,ob))
      File "site-packages/peak/storage/data_managers.py", line 318, in setstate
        ob.__setstate__(self._load(oid,ob))
      File "./userDM.py", line 14, in _load
        raise Exception(oid)
    Exception: 1


And here is SQL log if raise is commented:

    SELECT * FROM "user" WHERE uid=1
    SELECT * FROM "user" WHERE uid=1
    UPDATE "user" SET uid=1, login='hello' WHERE oid=1


If I exceute

    storage.begin(dm)
    user = dm[1]
    print user.login
    storage.commit(dm)

_load method is called only once.
I use python 2.3.3.

RadekK



More information about the PEAK mailing list