diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2011-10-28 17:46:28 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2011-10-28 17:46:28 -0400 |
| commit | 5d6376fbd5ca4103a26118a6fffd1e95be0d5161 (patch) | |
| tree | 2df70790564dd99556941091a1b32cc2fe28c875 /lib | |
| parent | a870d1c401fb4da3139743cafc6c5e29d988faee (diff) | |
| download | sqlalchemy-5d6376fbd5ca4103a26118a6fffd1e95be0d5161.tar.gz | |
- [bug] Fixed bug whereby a subclass of a subclass
using concrete inheritance in conjunction with
the new ConcreteBase or AbstractConcreteBase
would fail to apply the subclasses deeper than
one level to the "polymorphic loader" of each
base [ticket:2312]
- [bug] Fixed bug whereby a subclass of a subclass
using the new AbstractConcreteBase would fail
to acquire the correct "base_mapper" attribute
when the "base" mapper was generated, thereby
causing failures later on. [ticket:2312]
Diffstat (limited to 'lib')
| -rwxr-xr-x | lib/sqlalchemy/ext/declarative.py | 29 | ||||
| -rw-r--r-- | lib/sqlalchemy/orm/mapper.py | 3 |
2 files changed, 20 insertions, 12 deletions
diff --git a/lib/sqlalchemy/ext/declarative.py b/lib/sqlalchemy/ext/declarative.py index acfc09396..1f082adf1 100755 --- a/lib/sqlalchemy/ext/declarative.py +++ b/lib/sqlalchemy/ext/declarative.py @@ -1616,10 +1616,8 @@ class ConcreteBase(object): m = cls.__mapper__ if m.with_polymorphic: return - mappers = [ sm for sm in [ - _mapper_or_none(klass) - for klass in cls.__subclasses__() - ] if sm is not None] + [m] + + mappers = list(m.self_and_descendants) pjoin = cls._create_polymorphic_union(mappers) m._set_with_polymorphic(("*",pjoin)) m._set_polymorphic_on(pjoin.c.type) @@ -1661,13 +1659,22 @@ class AbstractConcreteBase(ConcreteBase): def __declare_last__(cls): if hasattr(cls, '__mapper__'): return - table = cls._create_polymorphic_union( - m for m in [ - _mapper_or_none(klass) - for klass in cls.__subclasses__() - ] if m is not None - ) - cls.__mapper__ = m = mapper(cls, table, polymorphic_on=table.c.type) + + # can't rely on 'self_and_descendants' here + # since technically an immediate subclass + # might not be mapped, but a subclass + # may be. + mappers = [] + stack = list(cls.__subclasses__()) + while stack: + klass = stack.pop() + stack.extend(klass.__subclasses__()) + mn = _mapper_or_none(klass) + if mn is not None: + mappers.append(mn) + pjoin = cls._create_polymorphic_union(mappers) + cls.__mapper__ = m = mapper(cls, pjoin, polymorphic_on=pjoin.c.type) + for scls in cls.__subclasses__(): sm = _mapper_or_none(scls) if sm.concrete and cls in scls.__bases__: diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index e6ec422b0..3a363e731 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -577,7 +577,8 @@ class Mapper(object): if mapper.polymorphic_on is not None: mapper._requires_row_aliasing = True self.batch = self.inherits.batch - self.base_mapper = self.inherits.base_mapper + for mp in self.self_and_descendants: + mp.base_mapper = self.inherits.base_mapper self.inherits._inheriting_mappers.add(self) self.passive_updates = self.inherits.passive_updates self._all_tables = self.inherits._all_tables |
