self._polymorphic_adapters.pop(m.local_table, None)
def _adapt_polymorphic_element(self, element):
+ if "parententity" in element._annotations:
+ search = element._annotations['parententity']
+ alias = self._polymorphic_adapters.get(search, None)
+ if alias:
+ return alias.adapt_clause(element)
+
if isinstance(element, expression.FromClause):
search = element
elif hasattr(element, 'table'):
search = element.table
else:
- search = None
+ return None
- if search is not None:
- alias = self._polymorphic_adapters.get(search, None)
- if alias:
- return alias.adapt_clause(element)
+ alias = self._polymorphic_adapters.get(search, None)
+ if alias:
+ return alias.adapt_clause(element)
def _adapt_col_list(self, cols):
return [
from sqlalchemy.testing import AssertsCompiledSQL, fixtures
from sqlalchemy import testing
from sqlalchemy.testing.schema import Table, Column
-from sqlalchemy.testing import assert_raises, eq_
+from sqlalchemy.testing import assert_raises, eq_, is_
class Company(fixtures.ComparableEntity):
pass
"JOIN ep2 ON anon_1.anon_2_base2_id = ep2.base2_id"
)
+class MultipleAdaptUsesEntityOverTableTest(AssertsCompiledSQL, fixtures.MappedTest):
+ __dialect__ = 'default'
+ run_create_tables = None
+
+ @classmethod
+ def define_tables(cls, metadata):
+ Table('a', metadata,
+ Column('id', Integer, primary_key=True),
+ Column('name', String)
+ )
+ Table('b', metadata,
+ Column('id', Integer, ForeignKey('a.id'), primary_key=True)
+ )
+ Table('c', metadata,
+ Column('id', Integer, ForeignKey('a.id'), primary_key=True),
+ Column('bid', Integer, ForeignKey('b.id'))
+ )
+ Table('d', metadata,
+ Column('id', Integer, ForeignKey('a.id'), primary_key=True),
+ Column('cid', Integer, ForeignKey('c.id'))
+ )
+
+ @classmethod
+ def setup_classes(cls):
+ class A(cls.Comparable):
+ pass
+ class B(A):
+ pass
+ class C(A):
+ pass
+ class D(A):
+ pass
+
+ @classmethod
+ def setup_mappers(cls):
+ A, B, C, D = cls.classes.A, cls.classes.B, cls.classes.C, cls.classes.D
+ a, b, c, d = cls.tables.a, cls.tables.b, cls.tables.c, cls.tables.d
+ mapper(A, a)
+ mapper(B, b, inherits=A)
+ mapper(C, c, inherits=A)
+ mapper(D, d, inherits=A)
+
+ def _two_join_fixture(self):
+ A, B, C, D = self.classes.A, self.classes.B, self.classes.C, self.classes.D
+ s = Session()
+ return s.query(B.name, C.name, D.name).select_from(B).\
+ join(C, C.bid == B.id).\
+ join(D, D.cid == C.id)
+
+ def test_two_joins_adaption(self):
+ a, b, c, d = self.tables.a, self.tables.b, self.tables.c, self.tables.d
+ q = self._two_join_fixture()
+
+ btoc = q._from_obj[0].left
+
+ ac_adapted = btoc.right.element.left
+ c_adapted = btoc.right.element.right
+
+ is_(ac_adapted.element, a)
+ is_(c_adapted.element, c)
+
+ ctod = q._from_obj[0].right
+ ad_adapted = ctod.left
+ d_adapted = ctod.right
+ is_(ad_adapted.element, a)
+ is_(d_adapted.element, d)
+
+ bname, cname, dname = q._entities
+
+ b_name_adapted = bname._resolve_expr_against_query_aliases(
+ q, bname.column, None)
+ c_name_adapted = cname._resolve_expr_against_query_aliases(
+ q, cname.column, None)
+ d_name_adapted = dname._resolve_expr_against_query_aliases(
+ q, dname.column, None)
+
+ assert bool(b_name_adapted == a.c.name)
+ assert bool(c_name_adapted == ac_adapted.c.name)
+ assert bool(d_name_adapted == ad_adapted.c.name)
+
+ def test_two_joins_sql(self):
+ q = self._two_join_fixture()
+ self.assert_compile(q,
+ "SELECT a.name AS a_name, a_1.name AS a_1_name, "
+ "a_2.name AS a_2_name "
+ "FROM a JOIN b ON a.id = b.id JOIN "
+ "(a AS a_1 JOIN c AS c_1 ON a_1.id = c_1.id) ON c_1.bid = b.id "
+ "JOIN (a AS a_2 JOIN d AS d_1 ON a_2.id = d_1.id) "
+ "ON d_1.cid = c_1.id"
+ )