OK, thanks for the reply Mike!

On Thursday, September 4, 2014 8:45:24 AM UTC-7, Michael Bayer wrote:
>
> this is probably more of a Pyramid question.
>
> I’m pretty allergic to traversal myself :)
>
>
> On Sep 3, 2014, at 2:58 PM, Milo Toor <milo...@gmail.com <javascript:>> 
> wrote:
>
> 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+...@googlegroups.com <javascript:>.
> To post to this group, send email to sqlal...@googlegroups.com 
> <javascript:>.
> Visit this group at http://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.
>
>
>

-- 
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.

Reply via email to