2012-08-28 16 views
6

ZODBを使用していますが、理解しているように、pickleを使用してクラスインスタンスを格納しています。私は私のmodels.pyファイルをいくつかのファイルに分割するリファクタリングをやっています。しかし、私がこれを行うと、私はpickleがクラス定義を見つけることができないと思うので、すでにデータベースに保存されているオブジェクトをロードすることはできません。この問題を処理する最善の方法は何ですか?pickle/zodb:動く.pyファイルをクラス定義で扱う方法?

答えて

4

エイリアスを作成できます。 1つのmodels.pyモジュールが複数の新しいモジュールに分割されているため、クラスを古い場所にインポートすることによってのみ行うことができます。

どちらの方法でも、インスタンスのピクルスの新しいコピーが新しい場所を参照します。 にすべてのの移動したクラスのインスタンスを強制的に書き込むことができれば、エイリアスを保持する必要はありません。これを行うには、再度書きたいインスタンス上に_p_changedTrueを設定します。

ので、エイリアスを作成するには、古い場所に移動するクラスをインポートすること:あなたが唯一のモジュール(すべて1つの新しい場所で発見されたので、同じクラスのの名前を変更する場合

from newmodule1 import MyClass1, MyClass2 
from newmodule2 import MyClass3 

、かもしれません私はそのような何かを行う必要がないように期待していたエイ

import sys 
import newmodule 

sys.modules['full.path.to.old.module] = newmodule 
+0

ああ、これは私が欲しいものと思われる。だからpickleは、既存のインスタンスをロードするとき、古い 'models.py'を見て、クラス名を見つけ、クラスを適切にロードしますが、ロードされたクラスは実際に新しい場所にあります...賢い – Claudiu

+0

@Claudiu:ので、クラスのための新しいピクルスを書くとき、それは新しいモジュールパスを使用します。 –

1

残念ながら、簡単な解決策はありません。あなたは

は、古いものを削除せずに自分のコード にリファクタリングクラスを追加
    1. 次のスキーマによってリファクタリングのもの(私は別のファイル/モジュールにあるクラスを意味する)を使用して古いスタイルのオブジェクトに変換することができますあなたのDB経由
    2. 徒歩ルートから始まり、データベースを圧縮する新しい同等
    3. すべて古いオブジェクトを交換する(それは重要です)
    4. 今あなたがソース
    5. から古いクラスを削除することができます
  • +0

    :輸入自身)のセットは、あなたも古い名前のためsys.modulesエントリを作成することができます。エイリアスソリューションは有望なようだ... – Claudiu

    +0

    @Claudiuエイリアス解決策が気に入らないのは、コードが混乱するからです。しかし、それはもちろん動作します:-) –

    3

    新しいクラスモデル構造への移行を実行せずにpickleをロード可能にしたい場合は、リファクタリングされたクラスのエイリアスインポートを古いmodel.pyの場所内で使用できます。

    関連する問題