2016-09-23 10 views
0

私は同じ列を持つ多くのテーブルを持っています。違いは、テーブル名自体です。コードの重複を最小限に抑えるために継承チェーンを設定したいと思います。以下の単層の継承は、私がそれを望むように動作します: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) 

をしかしHgmベースのすべてのインスタンスに対してAlignmentId列を指定するために私を必要とします。私の代わりにこれを行うには好きですが、私は実際にそれを使用しようとすると、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'>' 
+0

実際にsqliteを使用する予定ですか?または別のデータベース(いくつかの種類の継承をサポートするもの)? –

+0

データベースは実際にはsqliteです。 –

答えて

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を使用する方が簡単かもしれないことに注意してください。

+0

私が知る限り、ドキュメントの例はどれもこの問題を解決しません。 '__abstract__'を削除しても問題は解決しません。 mixinを使用すると助けになるかもしれません。 –

+0

@IanFiddesこれは、 'Base'ではなく' Hgm'から 'TransMap_HgmIntronVector'を派生させたからです。 – univerio

関連する問題