1

ZODB を使用してキャッシュ システムを作成しています。DB に配置するオブジェクトには、文字列に変換して Blob に保存する画像が含まれているため、 __getstate__andメソッドを使用する必要がありました。__setstate__

同様の問題を抱えている人を見つけられなかったので、何か愚かなことをしていると思います。私が抱えている問題は、次のテスト コードを実行することで確認できます。

from ZODB import FileStorage, DB
from persistent.mapping import PersistentMapping
import transaction

class Test(object):
    def __init__(self, a):
        self.a = a

    def __getstate__(self):
        print "Entering getstate for %s" % self.a
        return self.__dict__.copy()

    def __setstate__(self, state):
        print "Entering setstate for %s" % state["a"]
        self.__dict__ = state

print "Creating tests..."
tests = [ Test(i) for i in range(3) ]

print "Connecting to database..."
storage = FileStorage.FileStorage("./test_db.fs", blob_dir="./test_blobs")
db = DB(storage)
conn = db.open()
root = conn.root()
root["cache"] = PersistentMapping()
transaction.commit()

print "Adding tests to db..."
for idx,t in enumerate(tests):
    print "Starting transaction of idx %d" % idx
    root["cache"][idx] = t
    transaction.commit()

結果は次のとおりです。

Creating tests...
Connecting to database...
Adding tests to db...
Starting transaction of idx 0
Entering getstate for 0
Starting transaction of idx 1
Entering getstate for 0
Entering getstate for 1
Starting transaction of idx 2
Entering getstate for 0
Entering getstate for 1
Entering getstate for 2

出力からわかるように、各トランザクションは前のトランザクションごとに getstate メソッドを呼び出します。これは起こるはずですか/何が欠けていますか? トランザクションの使用を完全に誤解していますか? そのように PersistentMappings を使用しても問題ありませんか?

ZODB 3.10.3 と Python 2.6.3 を使用しています。

PS 通常、すべての操作を実行した後にコミットを実行するだけですが、ループは「キャッシュ」オブジェクトで可能な一連のメソッド呼び出しを表し、それぞれが ZODB からデータを追加または取得します。

あなたが与えることができる助けや理解に感謝します.

4

1 に答える 1

1

何時間もの追加の調査とテストの後、ここに私自身の質問に対する私の答えがあります...

簡単な答えは、persistent.Persistent からサブクラス化しなければならないということです。

__getstate__カスタムが必要なため、これを避けたいと思っていました (そして、私が行った調査のいくつかからは可能でしたが)、__setstate__Persistent を継承するには、それを正しく機能させるために追加の作業を行う必要があると考えました。保存しているオブジェクトが後で変更された場合に問題が発生する可能性がありますが、問題なく動作しているようです (ただし、ZODB にあるオブジェクトは変更していません)。

私がこれをどのように行っているかについて他のアドバイスや警告があれば、それは大歓迎です。提供できるものは何でもありがとう。

于 2011-07-14T15:11:55.533 に答える