Hello,
I have now a small example which illustrates the problem.
Program logic : each NPC inherites from Character and each NPC is based on
a prototype. It means, for example, that you can define the prototype
"red_guard" and then create 100 red guards all based on this prototype.
Most part of the NPC attributes are stored in the class Prototype. For
example, I can define in the prototype that a red guard has 1000 health
point and it will be reflected automatically in every NPC based on the
prototype. This is why, the __getattr_ function of NPC is looking in the
prototype attributes.
*Code:*
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy import orm
from sqlalchemy.orm import relationship
BaseBDD = declarative_base()
engine = create_engine('sqlite:///getattr_loop.db', echo=True)
Session = sessionmaker(bind=engine)
session = Session()
class Prototype(BaseBDD):
__tablename__ = "prototypes"
id = Column(Integer, primary_key=True)
npc = relationship("NPC", back_populates="prototype")
class Character(BaseBDD):
__tablename__ = "personnages"
id = Column(Integer, primary_key=True)
type = Column(String)
__mapper_args__ = {
'polymorphic_on':type,
'polymorphic_identity':'personnage'
}
class NPC(Character):
prototype_id = Column(ForeignKey('prototypes.id'))
prototype = relationship("Prototype", back_populates="npc")
__mapper_args__ = {
'polymorphic_identity':'npc'
}
def __init__(self, prototype):
Character.__init__(self)
self.prototype = prototype
prototype.npc.append(self)
def __getattr__(self, nom_attr):
return getattr(self.prototype, nom_attr)
BaseBDD.metadata.create_all(engine)
proto_jean = Prototype()
jean = NPC(proto_jean)
*Trace:*
Traceback (most recent call last):
File "C:\Users\Sven\Downloads\loop_test_trace.py", line 52, in <module>
jean = NPC(proto_jean)
File "<string>", line 2, in __init__
File "C:\Python34\lib\site-packages\sqlalchemy\orm\instrumentation.py",
line 379, in _new_state_if_none
if hasattr(instance, self.STATE_ATTR):
File "C:\Users\Sven\Downloads\loop_test_trace.py", line 47, in __getattr__
return getattr(self.prototype, nom_attr)
File "C:\Python34\lib\site-packages\sqlalchemy\orm\attributes.py", line
242, in __get__
return self.impl.get(instance_state(instance), dict_)
File "C:\Users\Sven\Downloads\loop_test_trace.py", line 47, in __getattr__
return getattr(self.prototype, nom_attr)
File "C:\Python34\lib\site-packages\sqlalchemy\orm\attributes.py", line
242, in __get__
return self.impl.get(instance_state(instance), dict_)
File "C:\Users\Sven\Downloads\loop_test_trace.py", line 47, in __getattr__
return getattr(self.prototype, nom_attr)
File "C:\Python34\lib\site-packages\sqlalchemy\orm\attributes.py", line
242, in __get__
return self.impl.get(instance_state(instance), dict_)
File "C:\Users\Sven\Downloads\loop_test_trace.py", line 47, in __getattr__
return getattr(self.prototype, nom_attr)
Unfortunately, the line "return getattr(self.prototype, nom_attr)" is
causing an endless loop.
Has someone a solution ? How can I avoid this loop ?
Thank you !
Sven
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable
Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.