More than one level of abstract concrete base classes does not work

Issue #3185 resolved
Alex Grönholm created an issue

The following code fails with AttributeError: 'NoneType' object has no attribute 'concrete':

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import AbstractConcreteBase, declarative_base

Base = declarative_base()


class Document(Base, AbstractConcreteBase):
    doctype = Column(Unicode, nullable=False)


class ContactDocument(Document):
    __abstract__ = True

    send_method = Column('sendmethod', Unicode)


class ActualDocument(ContactDocument):
    __tablename__ = 'actual_documents'
    __mapper_args__ = {'concrete': True, 'polymorphic_identity': 'actual'}

    id = Column(Integer, primary_key=True)

configure_mappers()

This is caused by the declare_first() in AbstractConcreteBase not checking if the target subclass has a mapper or not. Attached is the patch I was given to remedy the issue.

Comments (5)

  1. Mike Bayer repo owner
    • Fixed "'NoneType' object has no attribute 'concrete'" error when using :class:.AbstractConcreteBase in conjunction with a subclass that declares __abstract__. fixes #3185

    → <<cset 5a10b6a455f9>>

  2. Mike Bayer repo owner
    • Fixed "'NoneType' object has no attribute 'concrete'" error when using :class:.AbstractConcreteBase in conjunction with a subclass that declares __abstract__. fixes #3185

    Conflicts: test/ext/declarative/test_inheritance.py

    → <<cset 24cd39de0fc1>>

  3. Anatoly Bubenkov

    @zzzeek did it broke the former functionality of AbstractConcreteBase?

    class BaseLock(AbstractConcreteBase, Base):
    
        """Base lock."""
        @declared_attr
        def ticket(cls):
            """:py:class:`paylogic.service.ticket.models.Ticket` relationship."""
            return relation('Ticket', backref=backref('{0}_locks'.format(
                cls.__mapper_args__['polymorphic_identity']), viewonly=True))
    

    this fails with now:

    KeyError: 'polymorphic_identity'
    

    and declared_attr now receives BaseLock class in cls instead of concrete class

  4. Mike Bayer repo owner

    @bubenkov - can you please provide a complete test case? at the moment it seems you are just hitting the same thing as #3383.

  5. Log in to comment