summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES7
-rw-r--r--lib/sqlalchemy/ext/declarative.py9
-rw-r--r--test/ext/declarative.py21
3 files changed, 30 insertions, 7 deletions
diff --git a/CHANGES b/CHANGES
index f6b178f5c..2d03e7116 100644
--- a/CHANGES
+++ b/CHANGES
@@ -93,10 +93,13 @@ CHANGES
- Fixed a recursive pickling issue in serializer, triggered
by an EXISTS or other embedded FROM construct.
+ - Declarative locates the "inherits" class using a search
+ through __bases__, to skip over mixins that are local
+ to subclasses.
+
- Declarative figures out joined-table inheritance primary join
condition even if "inherits" mapper argument is given
- explicitly. Allows mixins to be used with joined table
- inheritance.
+ explicitly.
- Declarative will properly interpret the "foreign_keys" argument
on a backref() if it's a string.
diff --git a/lib/sqlalchemy/ext/declarative.py b/lib/sqlalchemy/ext/declarative.py
index f1b2e65fb..79677c084 100644
--- a/lib/sqlalchemy/ext/declarative.py
+++ b/lib/sqlalchemy/ext/declarative.py
@@ -400,6 +400,7 @@ from sqlalchemy.schema import Table, Column, MetaData
from sqlalchemy.orm import synonym as _orm_synonym, mapper, comparable_property, class_mapper
from sqlalchemy.orm.interfaces import MapperProperty
from sqlalchemy.orm.properties import PropertyLoader, ColumnProperty
+from sqlalchemy.orm.util import _is_mapped_class
from sqlalchemy import util, exceptions
from sqlalchemy.sql import util as sql_util
@@ -483,10 +484,10 @@ def _as_declarative(cls, classname, dict_):
mapper_args = getattr(cls, '__mapper_args__', {})
if 'inherits' not in mapper_args:
- inherits = cls.__mro__[1]
- inherits = cls._decl_class_registry.get(inherits.__name__, None)
- if inherits:
- mapper_args['inherits'] = inherits
+ for c in cls.__bases__:
+ if _is_mapped_class(c):
+ mapper_args['inherits'] = cls._decl_class_registry.get(c.__name__, None)
+ break
if hasattr(cls, '__mapper_cls__'):
mapper_cls = util.unbound_method_to_callable(cls.__mapper_cls__)
diff --git a/test/ext/declarative.py b/test/ext/declarative.py
index fb8190f2e..81009384b 100644
--- a/test/ext/declarative.py
+++ b/test/ext/declarative.py
@@ -768,7 +768,7 @@ class DeclarativeInheritanceTest(DeclarativeTestBase):
# compile succeeds because inherit_condition is honored
compile_mappers()
-
+
def test_joined(self):
class Company(Base, ComparableEntity):
__tablename__ = 'companies'
@@ -837,6 +837,25 @@ class DeclarativeInheritanceTest(DeclarativeTestBase):
def go():
assert sess.query(Person).filter(Manager.name=='dogbert').one().id
self.assert_sql_count(testing.db, go, 1)
+
+ def test_subclass_mixin(self):
+ class Person(Base, ComparableEntity):
+ __tablename__ = 'people'
+ id = Column('id', Integer, primary_key=True)
+ name = Column('name', String(50))
+ discriminator = Column('type', String(50))
+ __mapper_args__ = {'polymorphic_on':discriminator}
+
+ class MyMixin(object):
+ pass
+
+ class Engineer(MyMixin, Person):
+ __tablename__ = 'engineers'
+ __mapper_args__ = {'polymorphic_identity':'engineer'}
+ id = Column('id', Integer, ForeignKey('people.id'), primary_key=True)
+ primary_language = Column('primary_language', String(50))
+
+ assert class_mapper(Engineer).inherits is class_mapper(Person)
def test_with_undefined_foreignkey(self):
class Parent(Base):