5

列をポリモーフィックとしてEntity定義する宣言型の基本クラスがあります。name

class Entity(DeclarativeBase):
    name = Column('name', String(40))
    __mapper_args__ = {'polymorphic_on':name}

サブクラスでは、私は今言うことができます

class Experiment(Entity):
    __mapper_args__ = {'polymorphic_identity': "experiment"}

そして行われます。ただし、ライブラリのユーザー向けのサブクラスの作成を容易にしたいため、次のことが可能になります。

  • デフォルトの構文ほど複雑ではない、より良い構文を用意してください。これは、クラス内の単純な割り当てpoly_id = "exp"またはクラス デコレータの可能性があります。
  • polymorphic_identity が指定されていない場合は、サブクラスの名前から名前を抽出します。

メタクラスを使用してこれを実行しようとしました (2 番目の部分のみ)。

from sqlalchemy.ext.declarative import DeclarativeMeta

class Meta(type):
    def __init__(cls, classname, bases, dict_):
        dict_["__mapper_args__"] = {'polymorphic_identity': classname}
        return super(Meta, cls).__init__(classname, bases, dict_)

class CombinedMeta(Meta, DeclarativeMeta):
    pass

class Experiment(Entity):
    __metaclass__ = CombinedMeta

そのため、私の意見では、Metaを呼び出す前に名前を設定する必要DeclarativeMetaがありますが、機能していないようです。したがってDeclarativeMeta、ポリモーフィック名を設定すると思われる は、MRO を台無しにしたために変更を認識しないか、とにかく私がやっていることは明らかに間違っています。何を変更する必要がありますか、または SQLAlchemy にはすでにこのようなものがありますか?

4

2 に答える 2

7

dict_残念ですが、 を使用せずに属性を on に直接設定することで、問題は簡単に解決できますcls

class Meta(DeclarativeMeta):
    def __init__(cls, *args, **kw):
        if getattr(cls, '_decl_class_registry', None) is None:
            return # they use this in the docs, so maybe its not a bad idea
        cls.__mapper_args__ = {'polymorphic_identity': cls.__name__}
        return super(Meta, cls).__init__(*args, **kw)

class Experiment(Entity):
    __metaclass__ = Meta
于 2010-12-16T16:09:05.070 に答える
1

最近の sqlalchemy docs は、そのような目的で mixin クラスを使用する方法を示しています (バージョン >= 0.6 でのみ機能するのか、それともより適切に文書化されているのかはわかりません)。

http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/declarative/mixins.html

于 2010-12-16T15:25:08.147 に答える