table_to_map_config = dict(
(m.local_table, m)
- for m in _DeferredMapperConfig.classes_for_base(cls)
+ for m in _DeferredMapperConfig.
+ classes_for_base(cls, sort=False)
)
many_to_many = []
name_for_scalar_relationship,
name_for_collection_relationship,
generate_relationship)
- for map_config in table_to_map_config.values():
+
+ for map_config in _DeferredMapperConfig.classes_for_base(cls):
map_config.map()
local_table = map_config.local_table
local_cls = map_config.cls
+ if local_table is None:
+ return
for constraint in local_table.constraints:
if isinstance(constraint, ForeignKeyConstraint):
fks = constraint.elements
from ...orm.attributes import QueryableAttribute
from ...orm.base import _is_mapped_class
from ... import util, exc
+from ...util import topological
from ...sql import expression
from ... import event
from . import clsregistry
@classmethod
- def classes_for_base(cls, base_cls):
- return [m for m in cls._configs.values()
- if issubclass(m.cls, base_cls)]
+ def classes_for_base(cls, base_cls, sort=True):
+ classes_for_base = [m for m in cls._configs.values()
+ if issubclass(m.cls, base_cls)]
+ if not sort:
+ return classes_for_base
+
+ all_m_by_cls = dict(
+ (m.cls, m)
+ for m in classes_for_base
+ )
+
+ tuples = []
+ for m_cls in all_m_by_cls:
+ tuples.extend(
+ (all_m_by_cls[base_cls], all_m_by_cls[m_cls])
+ for base_cls in m_cls.__bases__
+ if base_cls in all_m_by_cls
+ )
+ return list(
+ topological.sort(
+ tuples,
+ classes_for_base
+ )
+ )
def map(self):
self._configs.pop(self._cls, None)
from sqlalchemy.orm import relationship, interfaces, backref
from sqlalchemy.ext.automap import generate_relationship
from sqlalchemy.testing.mock import Mock, call
+from sqlalchemy import Column, String, Table, Integer, ForeignKey
+from sqlalchemy import testing
class AutomapTest(fixtures.MappedTest):
@classmethod
(Base, interfaces.MANYTOONE, "users"),
(Base, interfaces.ONETOMANY, "addresses_collection"),
])
+
+
+class AutomapInhTest(fixtures.MappedTest):
+ @classmethod
+ def define_tables(cls, metadata):
+ Table('single', metadata,
+ Column('id', Integer, primary_key=True),
+ Column('type', String(10))
+ )
+
+ Table('joined_base', metadata,
+ Column('id', Integer, primary_key=True),
+ Column('type', String(10))
+ )
+
+ Table('joined_inh', metadata,
+ Column('id', Integer, ForeignKey('joined_base.id'), primary_key=True),
+ )
+
+ FixtureTest.define_tables(metadata)
+
+ def test_single_inheritance_reflect(self):
+ Base = automap_base()
+
+ class Single(Base):
+ __tablename__ = 'single'
+
+ type = Column(String)
+
+ __mapper_args__ = {"polymorphic_identity": "u0",
+ "polymorphic_on": type}
+
+ class SubUser1(Single):
+ __mapper_args__ = {"polymorphic_identity": "u1"}
+
+ class SubUser2(Single):
+ __mapper_args__ = {"polymorphic_identity": "u2"}
+
+ Base.prepare(engine=testing.db, reflect=True)
+
+ assert SubUser2.__mapper__.inherits is Single.__mapper__
+
+ def test_joined_inheritance_reflect(self):
+ Base = automap_base()
+
+ class Joined(Base):
+ __tablename__ = 'joined_base'
+
+ type = Column(String)
+
+ __mapper_args__ = {"polymorphic_identity": "u0",
+ "polymorphic_on": type}
+
+ class SubJoined(Joined):
+ __tablename__ = 'joined_inh'
+ __mapper_args__ = {"polymorphic_identity": "u1"}
+
+
+ Base.prepare(engine=testing.db, reflect=True)
+
+ assert SubJoined.__mapper__.inherits is Joined.__mapper__
+
+