Thanks for taking the time to look into it. It's kind of an odd case, so I
wasn't particularly expecting it to work out.
On Saturday, November 24, 2012 1:07:07 PM UTC-8, Michael Bayer wrote:
>
>
> I'd hate to make a bad story worse here, but in fact this is also the same
> eager loading pattern used in some other emails I've been answering here by
> Martin84...it's very unusual how these never-seen-before use cases suddenly
> pop up in pairs..but in any case, the eager loading here is actually broken
> in all versions, and it's not even possible to have two same-named
> attributes eager loading simultaneously on two subclasses of a
> with_polymorphic(). I've spent all day examining a fix, and it is turning
> out to be not at all trivial. So for now the new release of 0.8 will flat
> out raise an exception if this condition is detected. The eager loads
> otherwise return the incorrect results in many/most cases.
>
>
> On Nov 23, 2012, at 12:57 AM, Gerald Thibault wrote:
>
> I have a base class and 3 subclasses which inherit from it
> polymorphically. I also have a mixin, which attempts to add a relation to
> the 'Extra' class, which has a foreign key to the base class.
>
> Here is the runnable test.
>
> from sqlalchemy import *
> from sqlalchemy.ext.declarative import declared_attr, declarative_base
> from sqlalchemy.orm import Session, relationship
>
> Base = declarative_base()
>
> class Test(Base):
> __tablename__ = 'test'
>
> id = Column(Integer, primary_key=True)
> type = Column(String(12))
> name = Column(String(50))
>
> __mapper_args__ = {
> 'polymorphic_identity': 'base',
> 'polymorphic_on': type,
> 'with_polymorphic': '*',
> }
>
> class Extra(Base):
> __tablename__ = 'extra'
>
> id = Column(Integer, ForeignKey(Test.id), primary_key=True)
> extra_data = Column(Text, default='goats')
>
> class ExtraMixin(object):
>
> @declared_attr
> def extra(cls):
> return relationship(Extra, uselist=False, lazy='joined',
> primaryjoin=Extra.id==Test.id,
> foreign_keys=Extra.id,
> )
>
> class TestOne(Test):
> __tablename__ = 'test1'
> __mapper_args__ = { 'polymorphic_identity': 'one' }
>
> id = Column(Integer, ForeignKey(Test.id), primary_key=True)
> value1 = Column(String(16))
>
> class TestTwo(Test, ExtraMixin):
> __tablename__ = 'test2'
> __mapper_args__ = { 'polymorphic_identity': 'two' }
>
> id = Column(Integer, ForeignKey(Test.id), primary_key=True)
> value2 = Column(String(16))
>
> class TestThree(Test, ExtraMixin):
> __tablename__ = 'test3'
> __mapper_args__ = { 'polymorphic_identity': 'three' }
>
> id = Column(Integer, ForeignKey(Test.id), primary_key=True)
> value3 = Column(String(16))
>
>
> if __name__ == '__main__':
>
> import logging
> logging.basicConfig()
> logging.getLogger('sqlalchemy.orm').setLevel(logging.INFO)
>
> e = create_engine('sqlite:////tmp/foo.db', echo=True)
> Base.metadata = MetaData(e)
> Base.metadata.drop_all()
> Base.metadata.create_all()
> session = Session(e)
>
> session.query(Test).all()
> session.query(TestOne).all()
> session.query(TestTwo).all()
>
> Issuing the first query (note the with_polymorphic on the base) yields
> this:
>
> SELECT test.id AS test_id, test.type AS test_type, test.name AS
> test_name, test1.id AS test1_id, test1.value1 AS test1_value1, test2.idAS
> test2_id, test2.value2 AS test2_value2,
> test3.id AS test3_id, test3.value3 AS test3_value3, extra_1.id AS
> extra_1_id, extra_1.extra_data AS extra_1_extra_data, extra_2.id AS
> extra_2_id, extra_2.extra_data AS extra_2_extra_data
> FROM test LEFT OUTER JOIN test1 ON test.id = test1.id LEFT OUTER JOIN
> test2 ON test.id = test2.id LEFT OUTER JOIN test3 ON test.id = test3.idLEFT
> OUTER JOIN extra AS extra_1 ON
> extra_1.id = test.id LEFT OUTER JOIN extra AS extra_2 ON extra_2.id =
> test.id
>
> The extra table is being joined twice, because two subclasses inherit the
> relationship to the Extra class.
>
> Is there a way to prevent the relationship from being aliased? This is a
> one-to-one relation, so ideally a polymorphic query would issue left outer
> joins once for every involved table, all joined from Test.id, and it
> wouldn't alias any of them, so the resulting data would be usable for the
> active defined relationships (would I use contains_eager for something like
> this?). What can I do to make the mixed in table behave like the mapped
> polymorphic table, where the join is very clean and not aliased? There is a
> definite ideal join condition I am looking to achieve here, and I don't
> know how to get to it.
>
> Would I need to forego using eagerjoined relations due to the aliasing of
> the joined tables? If so, would I need to iteratively join new tables to
> mapper.mapped_table? I've tried that already, and ran into problems with
> Extra.id not being recognized as a key that can fold into the other
> equivalent keys, and it throws an error while trying to autogen the columns
> from the mapped_table. Is there a way to specify beforehand that certain
> columns should be folded into existing ones?
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/sqlalchemy/-/Mg8uL-3q0m8J.
> To post to this group, send email to [email protected]<javascript:>
> .
> To unsubscribe from this group, send email to
> [email protected] <javascript:>.
> For more options, visit this group at
> http://groups.google.com/group/sqlalchemy?hl=en.
>
>
>
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/sqlalchemy/-/BTiLRc1JtVEJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en.