使用sqlalchemy声明性基础的多级继承

时间:2016-09-23 17:33:08

标签: python sqlalchemy

我有很多具有相同列的表。不同之处在于表名本身。我想建立一个继承链,以尽量减少代码重复。以下单层继承按我希望的方式工作:

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)

但要求我为AlignmentId基地的每个实例指定Hgm列。我宁愿这样做,但在我尝试实际使用它时得到sqlalchemy.exc.InvalidRequestError

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()

导致错误

>>> metadata = Base.metadata
>>> Session = sessionmaker(bind=engine)
>>> session = Session()
>>> session.query(TransMap_HgmIntronVector).all()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  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 '<class '__main__.TransMap_HgmIntronVector'>'

1 个答案:

答案 0 :(得分:1)

一个例子是docs。特别是,__abstract__ = True不是必需的。这很好用:

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

请注意,将mixin用于相同的列可能更简单。