Using multiple levels of inheritance with sqlalchemy declarative base
<p>I have many tables with identical columns. The difference is the table names themselves. I want to set up a inheritance chain to minimize code duplication. The following single layer inheritance works the way I want it to:</p>

<pre><code>from sqlalchemy import Column, Integer, Text
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy.orm import sessionmaker

engine = sqlalchemy.create_engine('sqlite:///monDom5.db')


class Base(object):
    """base for all table classes"""
    __abstract__ = True
    __table_args__ = {'autoload': True, 'autoload_with': engine}
    @declared_attr
    def __tablename__(cls):
        return cls.__name__.lower()


Base = declarative_base(cls=Base)


class TransMap_HgmIntronVector(Base):
    AlignmentId = Column(Text, primary_key=True)
</code></pre>

<p>But requires me to specify the <code>AlignmentId</code> column for every instance of the <code>Hgm</code> base. I would instead like to do this, but get a <code>sqlalchemy.exc.InvalidRequestError</code> when I try to actually use it:</p>

<pre><code>from sqlalchemy import Column, Integer, Text
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy.orm import sessionmaker

engine = sqlalchemy.create_engine('sqlite:///monDom5.db')

class Base(object):
    """base for all table classes"""
    __abstract__ = True
    __table_args__ = {'autoload': True, 'autoload_with': engine}
    @declared_attr
    def __tablename__(cls):
        return cls.__name__.lower()


# model for all Hgm tables

class Hgm(Base):
    __abstract__ = True
    AlignmentId = Column(Text, primary_key=True)


Base = declarative_base(cls=Hgm)

class TransMap_HgmIntronVector(Hgm):
    pass



metadata = Base.metadata
Session = sessionmaker(bind=engine)
session = Session()
</code></pre>

<p>Leads to the error</p>

<pre><code>&gt;&gt;&gt; metadata = Base.metadata
&gt;&gt;&gt; Session = sessionmaker(bind=engine)
&gt;&gt;&gt; session = Session()
&gt;&gt;&gt; session.query(TransMap_HgmIntronVector).all()
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  File "/cluster/home/ifiddes/anaconda2/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 1260, in query
    return self._query_cls(entities, self, **kwargs)
  File "/cluster/home/ifiddes/anaconda2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 110, in __init__
    self._set_entities(entities)
  File "/cluster/home/ifiddes/anaconda2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 118, in _set_entities
    entity_wrapper(self, ent)
  File "/cluster/home/ifiddes/anaconda2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 3829, in __init__
    "expected - got '%r'" % (column, )
sqlalchemy.exc.InvalidRequestError: SQL expression, column, or mapped entity expected - got '&lt;class '__main__.TransMap_HgmIntronVector'&gt;'
</code></pre>

<p>An example is in the <a href="http://docs.sqlalchemy.org/en/latest/orm/extensions/declarative/mixins.html#augmenting-the-base" rel="nofollow">docs</a>. In particular, <code>__abstract__ = True</code> is not necessary. This works fine:</p>

<pre><code>class Base(object):
    @declared_attr
    def __tablename__(cls):
        return cls.__name__.lower()

class Hgm(Base):
    AlignmentId = Column(Text, primary_key=True)

Base = declarative_base(cls=Hgm)

class TransMap_HgmIntronVector(Base):
    pass
</code></pre>

<p>Note that it may be simpler to just use a mixin for the identical columns instead.</p>

python sqlalchemy