]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Union the exclude_properties of the inheriting mapper in declarative
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 26 Jan 2017 21:11:49 +0000 (16:11 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 30 Jan 2017 22:28:22 +0000 (17:28 -0500)
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
doc/build/changelog/changelog_11.rst
lib/sqlalchemy/ext/declarative/base.py
test/ext/declarative/test_inheritance.py

index 440b8294d68b84391cf77f26b764e15d713e0c38..8ed93ef74c4aafa047eea0af9e2f1f7f563c4313 100644 (file)
         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
index 16cb05e9c2a7f6e5f63a85686116168c63156f6e..3beee31910cc077fedd448fdc8c89edea09e2e7f 100644 (file)
@@ -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])
 
index a5a86b7c6f6165d31ecec3cc46d1225f4fcfe895..375bd6edcad659a29a4902671d05755ddd55f4d6 100644 (file)
@@ -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]"""