diff options
| -rw-r--r-- | CHANGES | 7 | ||||
| -rw-r--r-- | lib/sqlalchemy/ext/declarative.py | 9 | ||||
| -rw-r--r-- | test/ext/declarative.py | 21 |
3 files changed, 30 insertions, 7 deletions
@@ -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): |
