Re: [sqlalchemy] Wrapping polymorphic model for Pyramid traversal

2014-09-04 Thread Michael Bayer
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.t...@gmail.com 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+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.

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


Re: [sqlalchemy] Wrapping polymorphic model for Pyramid traversal

2014-09-04 Thread Milo Toor
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.


[sqlalchemy] Wrapping polymorphic model for Pyramid traversal

2014-09-03 Thread Milo Toor
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.