summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/build/changelog/changelog_09.rst9
-rw-r--r--lib/sqlalchemy/ext/declarative/api.py2
-rw-r--r--test/ext/declarative/test_inheritance.py29
3 files changed, 39 insertions, 1 deletions
diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst
index 7dd50739e..692c6e392 100644
--- a/doc/build/changelog/changelog_09.rst
+++ b/doc/build/changelog/changelog_09.rst
@@ -14,6 +14,15 @@
:version: 0.9.8
.. change::
+ :tags: bug, declarative, orm
+ :versions: 1.0.0
+ :tickets: 3185
+
+ Fixed "'NoneType' object has no attribute 'concrete'" error
+ when using :class:`.AbstractConcreteBase` in conjunction with
+ a subclass that declares ``__abstract__``.
+
+ .. change::
:tags: bug, engine
:versions: 1.0.0
:tickets: 3200
diff --git a/lib/sqlalchemy/ext/declarative/api.py b/lib/sqlalchemy/ext/declarative/api.py
index e84b21ad2..66fe05fd0 100644
--- a/lib/sqlalchemy/ext/declarative/api.py
+++ b/lib/sqlalchemy/ext/declarative/api.py
@@ -547,7 +547,7 @@ class AbstractConcreteBase(ConcreteBase):
for scls in cls.__subclasses__():
sm = _mapper_or_none(scls)
- if sm.concrete and cls in scls.__bases__:
+ if sm and sm.concrete and cls in scls.__bases__:
sm._set_concrete_base(m)
diff --git a/test/ext/declarative/test_inheritance.py b/test/ext/declarative/test_inheritance.py
index 5a99c9c5a..6ea37e4d3 100644
--- a/test/ext/declarative/test_inheritance.py
+++ b/test/ext/declarative/test_inheritance.py
@@ -1388,3 +1388,32 @@ class ConcreteExtensionConfigTest(
"WHERE something.id = pjoin.something_id AND something.id = :id_1)"
)
+ def test_abstract_in_hierarchy(self):
+ class Document(Base, AbstractConcreteBase):
+ doctype = Column(String)
+
+ class ContactDocument(Document):
+ __abstract__ = True
+
+ send_method = Column(String)
+
+ class ActualDocument(ContactDocument):
+ __tablename__ = 'actual_documents'
+ __mapper_args__ = {
+ 'concrete': True,
+ 'polymorphic_identity': 'actual'}
+
+ id = Column(Integer, primary_key=True)
+
+ configure_mappers()
+ session = Session()
+ self.assert_compile(
+ session.query(Document),
+ "SELECT pjoin.doctype AS pjoin_doctype, "
+ "pjoin.send_method AS pjoin_send_method, "
+ "pjoin.id AS pjoin_id, pjoin.type AS pjoin_type "
+ "FROM (SELECT actual_documents.doctype AS doctype, "
+ "actual_documents.send_method AS send_method, "
+ "actual_documents.id AS id, 'actual' AS type "
+ "FROM actual_documents) AS pjoin"
+ ) \ No newline at end of file