PYTHON-785 Don't use requests in GridFS.

This commit is contained in:
A. Jesse Jiryu Davis 2014-11-20 23:27:17 -05:00
parent 5aee3e1b31
commit fab611f63c
4 changed files with 36 additions and 33 deletions

View File

@ -118,19 +118,16 @@ class GridFS(object):
:Parameters:
- `data`: data to be written as a file.
- `**kwargs` (optional): keyword arguments for file creation
.. versionchanged:: 3.0
w=0 writes to GridFS are now prohibited.
"""
grid_file = GridIn(self.__collection, **kwargs)
# Start a request - necessary if w=0, harmless otherwise
request = self.__collection.database.connection.start_request()
try:
try:
grid_file.write(data)
finally:
grid_file.close()
grid_file.write(data)
finally:
# Ensure request is ended even if close() throws error
request.end()
grid_file.close()
return grid_file._id
def get(self, file_id):

View File

@ -27,7 +27,7 @@ from gridfs.errors import (CorruptGridFile,
from pymongo import ASCENDING
from pymongo.collection import Collection
from pymongo.cursor import Cursor
from pymongo.errors import DuplicateKeyError
from pymongo.errors import DuplicateKeyError, InvalidOperation
from pymongo.read_preferences import ReadPreference
try:
@ -130,29 +130,12 @@ class GridIn(object):
that is written to the file will be converted to
:class:`bytes`.
If you turn off write-acknowledgment for performance reasons, it is
critical to wrap calls to :meth:`write` and :meth:`close` within a
single request:
>>> from pymongo import MongoClient
>>> from gridfs import GridFS
>>> client = MongoClient(w=0) # turn off write acknowledgment
>>> fs = GridFS(client.database)
>>> gridin = fs.new_file()
>>> request = client.start_request()
>>> try:
... for i in range(10):
... gridin.write('foo')
... gridin.close()
... finally:
... request.end()
In Python 2.5 and later this code can be simplified with a
with-statement, see :doc:`/examples/requests` for more information.
:Parameters:
- `root_collection`: root collection to write to
- `**kwargs` (optional): file level options (see above)
.. versionchanged:: 3.0
w=0 writes to GridFS are now prohibited.
"""
if not isinstance(root_collection, Collection):
raise TypeError("root_collection must be an "
@ -321,6 +304,10 @@ class GridIn(object):
if self._closed:
raise ValueError("cannot write to a closed file")
# With w=0, 'filemd5' might run before the final chunks are written.
if 0 == self._coll.database.connection.write_concern.get('w'):
raise InvalidOperation('Cannot write file to GridFS with w=0')
try:
# file-like
read = data.read

View File

@ -32,13 +32,14 @@ from gridfs.grid_file import (DEFAULT_CHUNK_SIZE,
GridOutCursor)
from gridfs.errors import NoFile
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
from pymongo.errors import ConnectionFailure, InvalidOperation
from test import (client_knobs,
IntegrationTest,
host,
port,
unittest,
qcheck)
from test.utils import rs_or_single_client
class TestGridFileNoConnect(unittest.TestCase):
@ -609,6 +610,13 @@ Bye"""))
self.assertRaises(ConnectionFailure, infile.write, b'data')
self.assertRaises(ConnectionFailure, infile.close)
def test_unacknowledged(self):
# w=0 is prohibited.
infile = GridIn(rs_or_single_client(w=0).pymongo_test.fs)
with self.assertRaises(InvalidOperation):
infile.write(b'data')
if __name__ == "__main__":
unittest.main()

View File

@ -26,7 +26,7 @@ import gridfs
from bson.py3compat import u, StringIO, string_type
from pymongo.mongo_client import MongoClient
from pymongo.errors import ConnectionFailure
from pymongo.errors import ConnectionFailure, InvalidOperation
from pymongo.read_preferences import ReadPreference
from gridfs.errors import (FileExists,
NoFile)
@ -37,7 +37,11 @@ from test import (client_context,
host,
port,
IntegrationTest)
from test.utils import joinall, single_client, one, rs_client
from test.utils import (joinall,
single_client,
one,
rs_client,
rs_or_single_client)
class JustWrite(threading.Thread):
@ -426,6 +430,13 @@ class TestGridfs(IntegrationTest):
self.assertEqual(data, self.fs.get_version('f').read())
def test_unacknowledged(self):
# w=0 is prohibited.
fs = gridfs.GridFS(rs_or_single_client(w=0).pymongo_test)
with self.assertRaises(InvalidOperation):
fs.put(b'data')
class TestGridfsReplicaSet(TestReplicaSetClientBase):