Hi. I am trying to wrap a polymorphic model so that it can act as a traversal node in a Pyramid application:
from sqlalchemy import Column, Integer, String, create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() engine = create_engine('sqlite:///:memory:', echo=True) Session = sessionmaker(bind=engine) # This is the class we wish to wrap class Employee(Base): __tablename__ = 'employee' id = Column(Integer, primary_key=True) name = Column(String(50)) type = Column(String(20)) __mapper_args__ = { 'polymorphic_on': type, 'polymorphic_identity': 'employee' } class Manager(Employee): __mapper_args__ = { 'polymorphic_identity': 'manager' } class Engineer(Employee): __mapper_args__ = { 'polymorphic_identity': 'engineer' } class EmployeeInTraversal(Employee): """ Wraps the Employee class. This is to keep our models and our application logic decoupled. """ def __getitem__(self, key): """ Make the employee behave like a traversal node. :param key: The traversal key. If asked for tasks return the appropriate root factory """ if key == 'tasks': return 'TasksRootFactory()' raise KeyError # Create the tables Base.metadata.create_all(engine) # Create both a Manager and an Engineer manager = Manager(name='Taylor') engineer = Engineer(name='Sam') session = Session() session.add_all([manager, engineer]) session.commit() # somewhere a request is made for /employee/1/tasks... # Query for the engineer, somewhere in the EmployeeRootFactory wrapped_engineer = session.query(EmployeeInTraversal).get(1) # Traversal doing its thing. Here lies the trouble. engineer_tasks = wrapped_engineer['tasks'] The last line of this code throws a TypeError with the message *'NoneType' object has no attribute '__getitem__'*. Nothing is turned up by the query to EmployeeInTraversal. If the query is instead made with the Employee class, we get a similar TypeError: *'Manager' object has no attribute '__getitem__'*. So in other words, querying EmployeeInTraversal returns nothing, but querying Employee returns the object, although unwrapped. The reason for this, near as I can tell, is that the EmployeeInTraversal class is being interpreted as a subtype of Employee rather than as a wrapper for the class. I attribute this to the polymorphic nature of the Employee class, but at this point I'm really just banging my head against the wall. We would very much like to keep our models and application logic separate, and not embed traversal logic in the schema classes... Is there any way to wrap a polymorphic class without the wrapper being interpreted as a sub-type? -- 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 sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.