0

私は SQLAlchemy のプロジェクトに取り組んでいます。とCommand呼ばれるカスタムのシリアライゼーション/デシリアライゼーション メソッドを持つクラスがありtoBinArray()ますfromBinArray(bytes)。私はそれを TCP 通信に使用します (私の関数はより小さな出力を作成するため、pickle を使用したくありません)。

CommandCommandGetにはいくつかのサブクラスがあり、それらを、 などと呼びましょうCommandSet。これらには、独自の属性を追跡するための追加のメソッドと属性、およびシリアル化メソッドの再定義があります。polymorhic_identityメカニズムを使用して、それらすべてを1つのテーブルに保持しています。

問題は、多くのサブクラスがあり、それぞれに異なる属性があることです。以前にそれらすべてのマッピングを作成しましたが、このようにテーブルには膨大な量の列があります。

self.toBinArray()DB へのすべての書き込みの前にすべてのインスタンスを属性self._bin_array(バイナリ列に格納)にシリアライズ ( を使用) し、DB からインスタンスをロードするたびに属性をロード ( を使用) するメカニズムを書きたいと思いself.fromBinArray(value)ます。

私の質問の一部に対する答えはすでに見つかりました。デコレータを使用self.fromBinArray(self._bin_array)して関数を呼び出すことができます。@orm.reconstructorすべてのCommandサブクラスに継承され、適切に継承されたバージョンの を実行しますfromBinArray()私の質問は、DB への書き込み時にシリアル化を自動化する方法です (手動で設定できることはわかっていますself._bin_arrayが、それは非常に面倒です)。

PS私のコードの一部、私のメインクラス:

class Command(Base):
    __tablename__ = "commands"
    dbid = Column(Integer, Sequence("commands_seq"), primary_key = True)
    cmd_id = Column(SmallInteger)
    instance_dbid =  Column(Integer, ForeignKey("instances.dbid"))
    type = Column(String(20))
    _bin_array = Column(Binary)

    __mapper_args__ = {
    "polymorphic_on" : type,
    "polymorphic_identity" : "Command",
    }

    @orm.reconstructor
    def init_on_load(self):
        self.fromBinArray(self._bin_array)

    def fromBinArray(self, b):
        (...)
    def toBinArray(self):
        (...)

編集:解決策を見つけました(以下の回答)が、他に解決策はありますか?クラス本体内にイベントリスニング関数を挿入するためのショートカットでしょうか?

4

1 に答える 1

0

before_insert解決策は予想よりも簡単だったようです-イベントリスナーを(および/またはbefore_updateイベント)に使用する必要があります。という情報 (ソース) を見つけました

rebuildor() は、イベント API を使用してサブスクライブできる「インスタンス レベル」イベントのより大きなシステムへのショートカットです。これらのイベントの完全な API の説明については、InstanceEvents を参照してください。

そして、それは私に手がかりを与えました:

@event.listens_for(Command, 'before_insert', propagate = True)
def serialize_before_insert(mapper, connection, target):
    print("serialize_before_insert")
    target._bin_array = target.toBinArray()

関数を使用event.listen()してイベントリスナーをインスタンスにバインドすることもできますが、個人的にはデコレーターの方法を好みます。propagate = True)サブクラスがリスナーを継承できるように、宣言を追加することが非常に重要です。

于 2013-08-11T18:56:40.767 に答える