On 08/17/2010 11:21 AM, flzz wrote:
> from sqlalchemy.ext.declarative import declarative_base
> from sqlalchemy import create_engine, Column, Integer, String,
> ForeignKey
> from sqlalchemy.orm import sessionmaker, relationship
> from sqlalchemy.orm.collections import attribute_mapped_collection
>
> engine=create_engine('sqlite://', echo=True)
> Base = declarative_base(engine)
>
> def monkey_repr():
>     def __repr__(self):
>         """Show attribute values in the repr()."""
>         simple_props = ', '.join('%s=%r' % (attr, value)
>                                  for attr, value in
> sorted(vars(self).items())
>                                  if isinstance(value, (basestring,
> int)))
>         return '<%s (%s)>' % (type(self).__name__, simple_props)
>     return __repr__
>
> Base.__repr__ = monkey_repr()
>
> class Company(Base):
>     __tablename__ = 'companies'
>     id = Column(Integer, primary_key=True)
>     people = relationship('Person', lazy='joined',
>  
> collection_class=attribute_mapped_collection('name'))
>
> class Person(Base):
>     __tablename__ = 'people'
>     id = Column(Integer, primary_key=True)
>     _company_id = Column(Integer,  ForeignKey('companies.id'))
>     name = Column(String)
>     discriminator = Column('type', String(50))
>     __mapper_args__ = {'polymorphic_on': discriminator}
>
> class Engineer(Person):
>     __tablename__ = 'engineers'
>     __mapper_args__ = {'polymorphic_identity': 'engineer'}
>     name = Column(String)
>     department = Column(String)
>     id = Column(Integer, ForeignKey('people.id'), primary_key=True)
>     primary_language = Column(String(50))
>
> class Accountant(Person):
>     __tablename__ = 'accountants'
>     __mapper_args__ = {'polymorphic_identity': 'accountant'}
>     name = Column(String)
>     bank = Column(String)
>     id = Column(Integer, ForeignKey('people.id'), primary_key=True)
>     primary_language = Column(String(50))
>
> Base.metadata.create_all()
>
> sess = sessionmaker()()
>
> company = Company()
>
> for p in [Engineer(name='far'),
>           Person(name='nar'),
>           Engineer(name='zar', department='rover'),
>           Accountant(name='jak', bank='hsb')]:
>     company.people.set(p)
>
> sess.add(company)
> sess.commit()
> sess.expunge_all()
>
> print "\n#\n# Query for the first company \n#\n"
> c = sess.query(Company).first()
> print c.people
> print "\n#\n# This will issue another query even though lazy='joined'
> \n#\n"
> print c.people['zar'].department
>   

The easiest way is to add a "with_polymorphic" argument to
Person.__mapper_args__:

class Person(object):
    [...]
    __mapper_args__ = {'polymorphic_on': discriminator,
                       'with_polymorphic': '*'}

The downside is that this will always enable joinedloads on the subclass
tables when loaded via relationships. Seems like it would be nice to add
a "with_polymorphic" parameter to relationship().

-Conor

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to