ZODB事务提交多次调用__getstate__

时间:2011-07-13 19:08:18

标签: python zodb

我正在使用ZODB创建一个缓存系统。我放在数据库中的对象要求我使用__getstate____setstate__方法,因为它们包含我转换为字符串并存储在Blob中的图像。

我没有找到任何有类似问题的人,所以我假设我做的事情很愚蠢。通过运行以下测试代码可以看到我遇到的问题:

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。

P.S。 我知道通常你会在完成所有操作之后执行提交,但是循环表示在“缓存”对象中的一系列可能的方法调用,每个方法调用都从ZODB添加或检索数据。

感谢您提供的任何帮助或理解。

1 个答案:

答案 0 :(得分:1)

经过几个小时的额外研究和测试,这是我对自己问题的回答......

简单的答案是你必须从persistent.Persistent中继承。

我想避免这样做(而且我可以从我做过的一些研究中得到)因为我需要自定义__getstate____setstate__而且我认为继承Persistent I会必须做一些额外的工作才能使其正常工作。它似乎工作正常,但如果我存储的对象稍后更改(但是我们在ZODB中没有更改它们的话)可能会出现问题。

如果有人对我如何做到这一点有任何其他建议或警告,我将不胜感激。感谢你提供的任何东西。