Вызовы фиксации транзакции ZODB __getstate__ несколько раз - PullRequest
1 голос
/ 13 июля 2011

Я создаю систему кеширования с использованием 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 Ответ

1 голос
/ 14 июля 2011

После нескольких часов дополнительных исследований и испытаний вот мой ответ на мой собственный вопрос ...

Простой ответ: вы ДОЛЖНЫ подкласс от persistent.Persistent.

Я хотел избежать этого (и, хотя я мог это сделать из некоторых исследований, которые я проводил) из-за моей потребности в пользовательских __getstate__ и __setstate__, и я подумал, что для наследования Persistent мне придется сделать несколько дополнительная работа, чтобы заставить это работать правильно. Кажется, это работает нормально, хотя могут быть проблемы, если мои объекты, которые я храню, изменились позже (но я не изменяю их, когда они находятся в ZODB).

Если у кого-нибудь есть какие-либо другие советы или предупреждения о том, как я это делаю, это будет очень ценно. Спасибо за все, что вы можете предоставить.

...