MOTOR-439 Make Motor GridFSBucket match PyMongo

Add bucket_name, chunk_size_bytes, write_concern, and read_preference
parameters.
Deprecate the collection but still support it as an alias to
bucket_name.
This commit is contained in:
Shane Harvey 2019-10-28 17:17:51 -07:00
parent 163c56f6cc
commit b6bbe99766
3 changed files with 53 additions and 6 deletions

View File

@ -17,11 +17,13 @@ from __future__ import unicode_literals, absolute_import
"""GridFS implementation for Motor, an asynchronous driver for MongoDB."""
import textwrap
import warnings
import gridfs
import pymongo
import pymongo.errors
from gridfs import grid_file
from gridfs import (DEFAULT_CHUNK_SIZE,
grid_file)
from motor.core import (AgnosticBaseCursor,
AgnosticCollection,
@ -395,7 +397,9 @@ class AgnosticGridFSBucket(object):
upload_from_stream = AsyncCommand()
upload_from_stream_with_id = AsyncCommand()
def __init__(self, database, collection="fs", disable_md5=False):
def __init__(self, database, bucket_name="fs", disable_md5=False,
chunk_size_bytes=DEFAULT_CHUNK_SIZE, write_concern=None,
read_preference=None, collection=None):
"""Create a handle to a GridFS bucket.
Raises :exc:`~pymongo.errors.ConfigurationError` if `write_concern`
@ -418,11 +422,25 @@ class AgnosticGridFSBucket(object):
- `disable_md5` (optional): When True, MD5 checksums will not be
computed for uploaded files. Useful in environments where MD5
cannot be used for regulatory or other reasons. Defaults to False.
- `collection` (optional): Deprecated, an alias for `bucket_name`
that exists solely to provide backwards compatibility.
.. versionchanged:: 2.1
Added support for the `bucket_name`, `chunk_size_bytes`,
`write_concern`, and `read_preference` parameters.
Deprecated the `collection` parameter which is now an alias to
`bucket_name` (to match the GridFSBucket class in PyMongo).
.. versionadded:: 1.0
.. mongodoc:: gridfs
"""
# Preserve backwards compatibility of "collection" parameter
if collection is not None:
warnings.warn('the "collection" parameter is deprecated, use '
'"bucket_name" instead', DeprecationWarning,
stacklevel=2)
bucket_name = collection
db_class = create_class_with_framework(
AgnosticDatabase, self._framework, self.__module__)
@ -432,10 +450,16 @@ class AgnosticGridFSBucket(object):
self.__class__, database))
self.io_loop = database.get_io_loop()
self.collection = database[collection]
self.collection = database.get_collection(
bucket_name,
write_concern=write_concern,
read_preference=read_preference)
self.delegate = self.__delegate_class__(
database.delegate,
collection,
bucket_name,
chunk_size_bytes=chunk_size_bytes,
write_concern=write_concern,
read_preference=read_preference,
disable_md5=disable_md5)
def get_io_loop(self):

View File

@ -664,13 +664,13 @@ class GridFSBucket(Synchro):
find = WrapOutgoing()
def __init__(self, database, bucket_name='fs', disable_md5=False):
def __init__(self, database, *args, **kwargs):
if not isinstance(database, Database):
raise TypeError(
"Expected Database, got %s" % repr(database))
self.delegate = motor.MotorGridFSBucket(
database.delegate, bucket_name, disable_md5)
database.delegate, *args, **kwargs)
class GridIn(Synchro):

View File

@ -19,8 +19,11 @@ import asyncio
from io import BytesIO
from gridfs.errors import NoFile
from pymongo.write_concern import WriteConcern
from pymongo.read_preferences import ReadPreference
from motor.motor_asyncio import AsyncIOMotorGridFSBucket
from test.asyncio_tests import AsyncIOTestCase, asyncio_test
from test.utils import ignore_deprecations
class TestAsyncIOGridFSBucket(AsyncIOTestCase):
@ -58,3 +61,23 @@ class TestAsyncIOGridFSBucket(AsyncIOTestCase):
yield from self.bucket.open_download_stream(oid)
self.assertEqual(0, (yield from self.db.fs.files.count_documents({})))
self.assertEqual(0, (yield from self.db.fs.chunks.count_documents({})))
def test_init(self):
name = 'bucket'
wc = WriteConcern(w='majority', wtimeout=1000)
rp = ReadPreference.SECONDARY
size = 8
bucket = AsyncIOMotorGridFSBucket(
self.db, name, disable_md5=True, chunk_size_bytes=size,
write_concern=wc, read_preference=rp)
self.assertEqual(name, bucket.collection.name)
self.assertEqual(wc, bucket.collection.write_concern)
self.assertEqual(rp, bucket.collection.read_preference)
self.assertEqual(wc, bucket.delegate._chunks.write_concern)
self.assertEqual(rp, bucket.delegate._chunks.read_preference)
self.assertEqual(size, bucket.delegate._chunk_size_bytes)
@ignore_deprecations
def test_collection_param(self):
bucket = AsyncIOMotorGridFSBucket(self.db, collection='collection')
self.assertEqual('collection', bucket.collection.name)