diff options
| -rw-r--r-- | doc/build/changelog/changelog_10.rst | 11 | ||||
| -rw-r--r-- | lib/sqlalchemy/ext/declarative/api.py | 13 | ||||
| -rw-r--r-- | lib/sqlalchemy/ext/declarative/base.py | 1 | ||||
| -rw-r--r-- | test/ext/declarative/test_inheritance.py | 30 |
4 files changed, 53 insertions, 2 deletions
diff --git a/doc/build/changelog/changelog_10.rst b/doc/build/changelog/changelog_10.rst index 8ac3d5844..b5372be68 100644 --- a/doc/build/changelog/changelog_10.rst +++ b/doc/build/changelog/changelog_10.rst @@ -19,6 +19,17 @@ :version: 1.0.7 .. change:: + :tags: bug, orm, declarative + :tickets: 3480 + + Fixed bug in :class:`.AbstractConcreteBase` extension where + a column setup on the ABC base which had a different attribute + name vs. column name would not be correctly mapped on the final + base class. The failure on 0.9 would be silent whereas on + 1.0 it raised an ArgumentError, so may not have been noticed + prior to 1.0. + + .. change:: :tags: bug, orm :tickets: 3469 diff --git a/lib/sqlalchemy/ext/declarative/api.py b/lib/sqlalchemy/ext/declarative/api.py index 3d46bd4cb..dfc47ce95 100644 --- a/lib/sqlalchemy/ext/declarative/api.py +++ b/lib/sqlalchemy/ext/declarative/api.py @@ -7,7 +7,7 @@ """Public API functions and helpers for declarative.""" -from ...schema import Table, MetaData +from ...schema import Table, MetaData, Column from ...orm import synonym as _orm_synonym, \ comparable_property,\ interfaces, properties, attributes @@ -525,6 +525,17 @@ class AbstractConcreteBase(ConcreteBase): mappers.append(mn) pjoin = cls._create_polymorphic_union(mappers) + # For columns that were declared on the class, these + # are normally ignored with the "__no_table__" mapping, + # unless they have a different attribute key vs. col name + # and are in the properties argument. + # In that case, ensure we update the properties entry + # to the correct column from the pjoin target table. + declared_cols = set(to_map.declared_columns) + for k, v in list(to_map.properties.items()): + if v in declared_cols: + to_map.properties[k] = pjoin.c[v.key] + to_map.local_table = pjoin m_args = to_map.mapper_args_fn or dict diff --git a/lib/sqlalchemy/ext/declarative/base.py b/lib/sqlalchemy/ext/declarative/base.py index 57eb54f63..57305748c 100644 --- a/lib/sqlalchemy/ext/declarative/base.py +++ b/lib/sqlalchemy/ext/declarative/base.py @@ -463,7 +463,6 @@ class _MapperConfig(object): def _prepare_mapper_arguments(self): properties = self.properties - if self.mapper_args_fn: mapper_args = self.mapper_args_fn() else: diff --git a/test/ext/declarative/test_inheritance.py b/test/ext/declarative/test_inheritance.py index 3e6980190..274a6aa28 100644 --- a/test/ext/declarative/test_inheritance.py +++ b/test/ext/declarative/test_inheritance.py @@ -1453,3 +1453,33 @@ class ConcreteExtensionConfigTest( "FROM actual_documents) AS pjoin" ) + def test_column_attr_names(self): + """test #3480""" + + class Document(Base, AbstractConcreteBase): + documentType = Column('documenttype', String) + + class Offer(Document): + __tablename__ = 'offers' + + id = Column(Integer, primary_key=True) + __mapper_args__ = { + 'polymorphic_identity': 'offer' + } + + configure_mappers() + session = Session() + self.assert_compile( + session.query(Document), + "SELECT pjoin.documenttype AS pjoin_documenttype, " + "pjoin.id AS pjoin_id, pjoin.type AS pjoin_type FROM " + "(SELECT offers.documenttype AS documenttype, offers.id AS id, " + "'offer' AS type FROM offers) AS pjoin" + ) + + self.assert_compile( + session.query(Document.documentType), + "SELECT pjoin.documenttype AS pjoin_documenttype FROM " + "(SELECT offers.documenttype AS documenttype, offers.id AS id, " + "'offer' AS type FROM offers) AS pjoin" + ) |
