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/sqlalchemy/ext/declarative.py | |
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/sqlalchemy/ext/declarative.py')
-rwxr-xr-x | lib/sqlalchemy/ext/declarative.py | 29 |
1 files changed, 18 insertions, 11 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__: |