You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In ZODB 5.6 (and almost certainly previous versions), or any version of Python, FileStorage.iterator gracefully handles an empty storage, while record_iternext raises an exception.
>>> fromZODBimport config
>>> conf_str ="""
... <filestorage>
... path /tmp/Data.fs
... </filestorage>
... """
>>> storage = config.storageFromString(conf_str)
>>> list(storage.iterator())
[]
>>> storage.record_iternext(None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/ZODB/src/ZODB/FileStorage/FileStorage.py", line 1409, in record_iternext
oid = index.minKey(next)
File "//ZODB/src/ZODB/fsIndex.py", line 236, in minKey
smallest_prefix = self._data.minKey()
ValueError: empty tree
This is a problem because record_iternext doesn't specify any behaviour around empty storages; it doesn't mention exceptions. I would expect record_iternext to behave like iterator and return a slate of None values, or specify what exception to watch for in that specific case (StopIteration?).
The existing documentation and example, and the iteration-cookie design of record_iternext, suggest that returning a bunch of Nones is likely to break existing clients just as badly as a new exception, so perhaps just specifying the ValueError is the most practical approach.
This comes up in the context of RelStorage and copyTransactionsFrom: For history-free RelStorage instances, it's substantially faster to implement copyTransactionsFrom using record_iternext than iterator().
The text was updated successfully, but these errors were encountered:
jamadden
added a commit
to zodb/relstorage
that referenced
this issue
Oct 9, 2020
Add tests with blobs, more incremental testing, and tests with history-free destinations.
This found, and added a workaround for, zopefoundation/ZODB#330
In ZODB 5.6 (and almost certainly previous versions), or any version of Python,
FileStorage.iterator
gracefully handles an empty storage, whilerecord_iternext
raises an exception.This is a problem because
record_iternext
doesn't specify any behaviour around empty storages; it doesn't mention exceptions. I would expectrecord_iternext
to behave likeiterator
and return a slate of None values, or specify what exception to watch for in that specific case (StopIteration?).The existing documentation and example, and the iteration-cookie design of
record_iternext
, suggest that returning a bunch of Nones is likely to break existing clients just as badly as a new exception, so perhaps just specifying theValueError
is the most practical approach.This comes up in the context of RelStorage and
copyTransactionsFrom
: For history-free RelStorage instances, it's substantially faster to implementcopyTransactionsFrom
usingrecord_iternext
thaniterator()
.The text was updated successfully, but these errors were encountered: