summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/ext/declarative.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2011-10-28 17:46:28 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2011-10-28 17:46:28 -0400
commit5d6376fbd5ca4103a26118a6fffd1e95be0d5161 (patch)
tree2df70790564dd99556941091a1b32cc2fe28c875 /lib/sqlalchemy/ext/declarative.py
parenta870d1c401fb4da3139743cafc6c5e29d988faee (diff)
downloadsqlalchemy-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-xlib/sqlalchemy/ext/declarative.py29
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__: