summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2017-01-26 16:11:49 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2017-01-30 17:28:22 -0500
commit9a5943bf76cd436484a85a6d9478507c9bac3b08 (patch)
treee89680d1af5e8db4c66bd5474029c34ea79f2ff0
parent5ef2fde8fb25e30452e06764bf0ec022eb23c15d (diff)
downloadsqlalchemy-9a5943bf76cd436484a85a6d9478507c9bac3b08.tar.gz
Union the exclude_properties of the inheriting mapper in declarative
Fixed bug where the "automatic exclude" feature of declarative that ensures a column local to a single table inheritance subclass does not appear as an attribute on other derivations of the base would not take effect for multiple levels of subclassing from the base. Change-Id: Ibf67b631b4870dd1bd159f7d6085549d299fffe0 Fixes: #3895
-rw-r--r--doc/build/changelog/changelog_11.rst9
-rw-r--r--lib/sqlalchemy/ext/declarative/base.py8
-rw-r--r--test/ext/declarative/test_inheritance.py39
3 files changed, 53 insertions, 3 deletions
diff --git a/doc/build/changelog/changelog_11.rst b/doc/build/changelog/changelog_11.rst
index 440b8294d..8ed93ef74 100644
--- a/doc/build/changelog/changelog_11.rst
+++ b/doc/build/changelog/changelog_11.rst
@@ -53,6 +53,15 @@
Added :meth:`.baked.Result.scalar` and :meth:`.baked.Result.count`
to the "baked" query system.
+ .. change:: 3895
+ :tags: bug, orm, declarative
+ :tickets: 3895
+
+ Fixed bug where the "automatic exclude" feature of declarative that
+ ensures a column local to a single table inheritance subclass does
+ not appear as an attribute on other derivations of the base would
+ not take effect for multiple levels of subclassing from the base.
+
.. change:: 3893
:tags: bug, orm
:tickets: 3893
diff --git a/lib/sqlalchemy/ext/declarative/base.py b/lib/sqlalchemy/ext/declarative/base.py
index 16cb05e9c..3beee3191 100644
--- a/lib/sqlalchemy/ext/declarative/base.py
+++ b/lib/sqlalchemy/ext/declarative/base.py
@@ -492,8 +492,12 @@ class _MapperConfig(object):
if 'exclude_properties' not in mapper_args:
mapper_args['exclude_properties'] = exclude_properties = \
- set([c.key for c in inherited_table.c
- if c not in inherited_mapper._columntoproperty])
+ set(
+ [c.key for c in inherited_table.c
+ if c not in inherited_mapper._columntoproperty]
+ ).union(
+ inherited_mapper.exclude_properties or ()
+ )
exclude_properties.difference_update(
[c.key for c in self.declared_columns])
diff --git a/test/ext/declarative/test_inheritance.py b/test/ext/declarative/test_inheritance.py
index a5a86b7c6..375bd6edc 100644
--- a/test/ext/declarative/test_inheritance.py
+++ b/test/ext/declarative/test_inheritance.py
@@ -1,6 +1,6 @@
from sqlalchemy.testing import eq_, assert_raises, \
- assert_raises_message, is_, is_true
+ assert_raises_message, is_, is_true, is_false
from sqlalchemy.ext import declarative as decl
import sqlalchemy as sa
from sqlalchemy import testing
@@ -485,6 +485,43 @@ class DeclarativeInheritanceTest(DeclarativeTestBase):
).one(),
Engineer(name='vlad', primary_language='cobol'))
+ def test_single_cols_on_sub_base_of_joined(self):
+ """test [ticket:3895]"""
+
+ class Person(Base):
+ __tablename__ = "person"
+
+ id = Column(Integer, primary_key=True)
+ type = Column(String)
+
+ __mapper_args__ = {
+ "polymorphic_on": type,
+ }
+
+ class Contractor(Person):
+ contractor_field = Column(String)
+
+ __mapper_args__ = {
+ "polymorphic_identity": "contractor",
+ }
+
+ class Employee(Person):
+ __tablename__ = "employee"
+
+ id = Column(Integer, ForeignKey(Person.id), primary_key=True)
+
+ class Engineer(Employee):
+ __mapper_args__ = {
+ "polymorphic_identity": "engineer",
+ }
+
+ configure_mappers()
+
+ is_false(hasattr(Person, 'contractor_field'))
+ is_true(hasattr(Contractor, 'contractor_field'))
+ is_false(hasattr(Employee, 'contractor_field'))
+ is_false(hasattr(Engineer, 'contractor_field'))
+
def test_single_cols_on_sub_to_joined(self):
"""test [ticket:3797]"""