arskom/rpclib — Issue #105: Infinite loop with the sqlalchemy backend
Author: SunWukong
Created: 2011-10-26 09:56:53+00:00
State: open

Hi !

I will start with the error message :
...
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 307, in _new_state_if_none
_new_state_if_none(instance)
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 307, in _new_state_if_none
_new_state_if_none(instance)
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 307, in _new_state_if_none
_new_state_if_none(instance)
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 307, in _new_state_if_none
_new_state_if_none(instance)
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 307, in _new_state_if_none
_new_state_if_none(instance)
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 307, in _new_state_if_none
_new_state_if_none(instance)
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 307, in _new_state_if_none
_new_state_if_none(instance)
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 307, in _new_state_if_none
_new_state_if_none(instance)
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 307, in _new_state_if_none
_new_state_if_none(instance)
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 307, in _new_state_if_none
_new_state_if_none(instance)
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 307, in _new_state_if_none
_new_state_if_none(instance)
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 307, in _new_state_if_none
_new_state_if_none(instance)
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 307, in _new_state_if_none
_new_state_if_none(instance)
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 306, in _new_state_if_none
return self._subclass_manager(instance.__class__).\
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 135, in _subclass_manager
manager = manager_of_class(cls)
File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 609, in manager_of_class
return cls.__dict__.get(ClassManager.MANAGER_ATTR, None)
RuntimeError: maximum recursion depth exceeded while calling a Python object
...
The loop is on File "C:\Python27\lib\site-packages\sqlalchemy-0.7.2-py2.7-win32.egg\sqlalchemy\orm\instrumentation.py", line 307

The context :
Python 2.7
SQLAlchemy 0.7.2 (MySQL DB)
rpclib 2.4.4 or a dev repo provided by Burak (see issue #104)

I've got this class that maps a MySQL table :
...

class Patient(TableModel, DeclarativeBase):
__namespace__ = nameSpace
__tablename__ = 'fiche_patient'

patient_id = Column(sqlalchemy.Integer, primary_key=True)
user_id = Column(sqlalchemy.Integer)
nom = Column(sqlalchemy.String(50))
prenom = Column(sqlalchemy.String(25))
telephone = Column(sqlalchemy.String(20))
telephone2 = Column(sqlalchemy.String(20))
adresse = Column(sqlalchemy.String(160))
code_postal = Column(sqlalchemy.String(10))
ville = Column(sqlalchemy.String(30))
nom_med = Column(sqlalchemy.String(50))
tel_med = Column(sqlalchemy.String(20))
tel_med2 = Column(sqlalchemy.String(20))
note = Column(sqlalchemy.Text)
photo = Column(sqlalchemy.LargeBinary)
maj = Column(sqlalchemy.String(1))
patient_id_tpz = Column(sqlalchemy.Integer)
...

And here's the called method of the web service :
...
@rpc(Int(min_occurs=1, max_occurs=1),
String(min_occurs=1, max_occurs=1),
Array(Patient),
_returns=Int(min_occurs=1, max_occurs=1))
def tpz_setPatients(ctx, user_id, password, patients):
if do_verifPassword(ctx, user_id, password):
idx = 0
for patient in patients:
idx += 1
patient.user_id = user_id
ctx.udc.session.add(patient)
return idx
else:
return -1
...