你如何检查你是否在Python中使用ZODB进行交易?

时间:2013-09-27 22:23:41

标签: python transactions zodb

我正在编写一些涉及ZODB的测试,但由于我在某些单元测试中遇到的错误,我被困了很长时间。我们称之为Test_B

Failure/Error: 'NoneType' object has no attribute 'sortKey'
...
 File <<< my code somewhere >>>
     transaction.commit()
 File "/usr/local/lib/python2.7/site-packages/transaction/_manager.py", line 111, in commit
     return self.get().commit()
 File "/usr/local/lib/python2.7/site-packages/transaction/_transaction.py", line 280, in commit
     reraise(t, v, tb)
 File "/usr/local/lib/python2.7/site-packages/transaction/_transaction.py", line 271, in commit
     self._commitResources()
 File "/usr/local/lib/python2.7/site-packages/transaction/_transaction.py", line 386, in _commitResources
     L.sort(key=rm_key)
 File "/usr/local/lib/python2.7/site-packages/transaction/_transaction.py", line 555, in rm_key
     return func()
 File "/usr/local/lib/python2.7/site-packages/ZODB/Connection.py", line 813, in sortKey
     return "%s:%s" % (self._storage.sortKey(), id(self))

幸运的是,我最终发现忘记在transaction.commit()之前运行的测试中调用Test_B(不出所料)Test_A。因此,日志记录的事件序列如下:

<<< Test_A begins >>>
23:01:41 DEBUG    txn.140735119446400: new transaction
...
<<< no further mentions of txn.140735119446400 being committed or aborted >>>
<<< Test_A ends >>>
<<< Test_B begins >>>
23:01:41 DEBUG    txn.140735119446400: new transaction
23:01:41 DEBUG    my_spec: *** MANUALLY altered DB in Test_B body
...
<<< Test_B bails out due to error >>>

请注意Test A成功:这是错误的!我希望Test A失败并告诉我,我在忘记提交的事务中有未完成的更改。

如何使用ZODB执行此操作?我在文档中找不到任何可用于查明我是否在进行更改的事务中的内容。

显然,通过该检查,我可以将其粘贴到套件中所有单元测试的AfterEach块中。

1 个答案:

答案 0 :(得分:1)

您通常会在测试之间关闭与ZODB的连接,以确保测试被隔离。

使用活动事务关闭ZODB连接将引发异常:

>>> from ZODB.FileStorage import FileStorage
>>> from ZODB.DB import DB
>>> storage = FileStorage('Data.fs')
>>> db = DB(storage)
>>> connection = db.open()
>>> root = connection.root()
>>> root['foo'] = 'bar'
>>> connection.close()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mj/Development/venvs/stackoverflow-2.7/lib/python2.7/site-packages/ZODB/Connection.py", line 286, in close
    raise ConnectionStateError("Cannot close a connection joined to "
ZODB.POSException.ConnectionStateError: Cannot close a connection joined to a transaction