MOTOR-420 Remove legacy APIs/patterns from documentation (#85)
This commit is contained in:
parent
70185d1361
commit
84f8a051d0
@ -5,7 +5,7 @@
|
||||
|
||||
.. autoclass:: AsyncIOMotorCursor
|
||||
:members:
|
||||
|
||||
:inherited-members:
|
||||
|
||||
:class:`~motor.motor_asyncio.AsyncIOMotorCommandCursor`
|
||||
=======================================================
|
||||
@ -14,3 +14,4 @@
|
||||
|
||||
.. autoclass:: AsyncIOMotorCommandCursor
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
:members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
:class:`~motor.motor_tornado.MotorCommandCursor`
|
||||
================================================
|
||||
|
||||
|
||||
@ -37,14 +37,13 @@ Store blobs of data in `GridFS <http://dochub.mongodb.org/core/gridfs>`_.
|
||||
|
||||
Delete a file's metadata and data chunks from a GridFS bucket::
|
||||
|
||||
@gen.coroutine
|
||||
def delete():
|
||||
async def delete():
|
||||
my_db = MotorClient().test
|
||||
fs = MotorGridFSBucket(my_db)
|
||||
# Get _id of file to delete
|
||||
file_id = yield fs.upload_from_stream("test_file",
|
||||
file_id = await fs.upload_from_stream("test_file",
|
||||
b"data I want to store!")
|
||||
yield fs.delete(file_id)
|
||||
await fs.delete(file_id)
|
||||
|
||||
Raises :exc:`~gridfs.errors.NoFile` if no file with file_id exists.
|
||||
|
||||
@ -58,16 +57,15 @@ Store blobs of data in `GridFS <http://dochub.mongodb.org/core/gridfs>`_.
|
||||
Downloads the contents of the stored file specified by file_id and
|
||||
writes the contents to `destination`::
|
||||
|
||||
@gen.coroutine
|
||||
def download():
|
||||
async def download():
|
||||
my_db = MotorClient().test
|
||||
fs = MotorGridFSBucket(my_db)
|
||||
# Get _id of file to read
|
||||
file_id = yield fs.upload_from_stream("test_file",
|
||||
file_id = await fs.upload_from_stream("test_file",
|
||||
b"data I want to store!")
|
||||
# Get file to write to
|
||||
file = open('myfile','wb+')
|
||||
yield fs.download_to_stream(file_id, file)
|
||||
await fs.download_to_stream(file_id, file)
|
||||
file.seek(0)
|
||||
contents = file.read()
|
||||
|
||||
@ -86,13 +84,12 @@ Store blobs of data in `GridFS <http://dochub.mongodb.org/core/gridfs>`_.
|
||||
|
||||
For example::
|
||||
|
||||
@gen.coroutine
|
||||
def download_by_name():
|
||||
async def download_by_name():
|
||||
my_db = MotorClient().test
|
||||
fs = MotorGridFSBucket(my_db)
|
||||
# Get file to write to
|
||||
file = open('myfile','wb')
|
||||
yield fs.download_to_stream_by_name("test_file", file)
|
||||
await fs.download_to_stream_by_name("test_file", file)
|
||||
|
||||
Raises :exc:`~gridfs.errors.NoFile` if no such version of
|
||||
that file exists.
|
||||
@ -165,15 +162,14 @@ Store blobs of data in `GridFS <http://dochub.mongodb.org/core/gridfs>`_.
|
||||
|
||||
Opens a stream to read the contents of the stored file specified by file_id::
|
||||
|
||||
@gen.coroutine
|
||||
def download_stream():
|
||||
async def download_stream():
|
||||
my_db = MotorClient().test
|
||||
fs = MotorGridFSBucket(my_db)
|
||||
# get _id of file to read.
|
||||
file_id = yield fs.upload_from_stream("test_file",
|
||||
file_id = await fs.upload_from_stream("test_file",
|
||||
b"data I want to store!")
|
||||
grid_out = yield fs.open_download_stream(file_id)
|
||||
contents = yield grid_out.read()
|
||||
grid_out = await fs.open_download_stream(file_id)
|
||||
contents = await grid_out.read()
|
||||
|
||||
Raises :exc:`~gridfs.errors.NoFile` if no file with file_id exists.
|
||||
|
||||
@ -186,15 +182,14 @@ Store blobs of data in `GridFS <http://dochub.mongodb.org/core/gridfs>`_.
|
||||
|
||||
Opens a stream to read the contents of `filename` and optional `revision`::
|
||||
|
||||
@gen.coroutine
|
||||
def download_by_name():
|
||||
async def download_by_name():
|
||||
my_db = MotorClient().test
|
||||
fs = MotorGridFSBucket(my_db)
|
||||
# get _id of file to read.
|
||||
file_id = yield fs.upload_from_stream("test_file",
|
||||
file_id = await fs.upload_from_stream("test_file",
|
||||
b"data I want to store!")
|
||||
grid_out = yield fs.open_download_stream_by_name(file_id)
|
||||
contents = yield grid_out.read()
|
||||
grid_out = await fs.open_download_stream_by_name(file_id)
|
||||
contents = await grid_out.read()
|
||||
|
||||
Raises :exc:`~gridfs.errors.NoFile` if no such version of
|
||||
that file exists.
|
||||
@ -225,16 +220,15 @@ Store blobs of data in `GridFS <http://dochub.mongodb.org/core/gridfs>`_.
|
||||
Specify the filename, and add any additional information in the metadata
|
||||
field of the file document or modify the chunk size::
|
||||
|
||||
@gen.coroutine
|
||||
def upload():
|
||||
async def upload():
|
||||
my_db = MotorClient().test
|
||||
fs = MotorGridFSBucket(my_db)
|
||||
grid_in, file_id = fs.open_upload_stream(
|
||||
"test_file", chunk_size_bytes=4,
|
||||
metadata={"contentType": "text/plain"})
|
||||
|
||||
yield grid_in.write(b"data I want to store!")
|
||||
yield grid_in.close() # uploaded on close
|
||||
await grid_in.write(b"data I want to store!")
|
||||
await grid_in.close() # uploaded on close
|
||||
|
||||
Returns an instance of :class:`MotorGridIn`.
|
||||
|
||||
@ -242,8 +236,8 @@ Store blobs of data in `GridFS <http://dochub.mongodb.org/core/gridfs>`_.
|
||||
that file exists.
|
||||
Raises :exc:`~ValueError` if `filename` is not a string.
|
||||
|
||||
In a Python 3.5 native coroutine, the "async with" statement calls
|
||||
:meth:`~MotorGridIn.close` automatically::
|
||||
Using the "async with" statement calls :meth:`~MotorGridIn.close`
|
||||
automatically::
|
||||
|
||||
async def upload():
|
||||
my_db = MotorClient().test
|
||||
@ -269,8 +263,7 @@ Store blobs of data in `GridFS <http://dochub.mongodb.org/core/gridfs>`_.
|
||||
Specify the filed_id and filename, and add any additional information in
|
||||
the metadata field of the file document, or modify the chunk size::
|
||||
|
||||
@gen.coroutine
|
||||
def upload():
|
||||
async def upload():
|
||||
my_db = MotorClient().test
|
||||
fs = MotorGridFSBucket(my_db)
|
||||
grid_in, file_id = fs.open_upload_stream_with_id(
|
||||
@ -279,8 +272,8 @@ Store blobs of data in `GridFS <http://dochub.mongodb.org/core/gridfs>`_.
|
||||
chunk_size_bytes=4,
|
||||
metadata={"contentType": "text/plain"})
|
||||
|
||||
yield grid_in.write(b"data I want to store!")
|
||||
yield grid_in.close() # uploaded on close
|
||||
await grid_in.write(b"data I want to store!")
|
||||
await grid_in.close() # uploaded on close
|
||||
|
||||
Returns an instance of :class:`MotorGridIn`.
|
||||
|
||||
@ -305,15 +298,14 @@ Store blobs of data in `GridFS <http://dochub.mongodb.org/core/gridfs>`_.
|
||||
For example::
|
||||
|
||||
|
||||
@gen.coroutine
|
||||
def rename():
|
||||
async def rename():
|
||||
my_db = MotorClient().test
|
||||
fs = MotorGridFSBucket(my_db)
|
||||
# get _id of file to read.
|
||||
file_id = yield fs.upload_from_stream("test_file",
|
||||
file_id = await fs.upload_from_stream("test_file",
|
||||
b"data I want to store!")
|
||||
|
||||
yield fs.rename(file_id, "new_test_name")
|
||||
await fs.rename(file_id, "new_test_name")
|
||||
|
||||
Raises :exc:`~gridfs.errors.NoFile` if no file with file_id exists.
|
||||
|
||||
@ -331,11 +323,10 @@ Store blobs of data in `GridFS <http://dochub.mongodb.org/core/gridfs>`_.
|
||||
it to the file `filename`. Source can be a string or file-like object.
|
||||
For example::
|
||||
|
||||
@gen.coroutine
|
||||
def upload_from_stream():
|
||||
async def upload_from_stream():
|
||||
my_db = MotorClient().test
|
||||
fs = MotorGridFSBucket(my_db)
|
||||
file_id = yield fs.upload_from_stream(
|
||||
file_id = await fs.upload_from_stream(
|
||||
"test_file",
|
||||
b"data I want to store!",
|
||||
chunk_size_bytes=4,
|
||||
@ -365,11 +356,10 @@ Store blobs of data in `GridFS <http://dochub.mongodb.org/core/gridfs>`_.
|
||||
it to the file `filename`. Source can be a string or file-like object.
|
||||
For example::
|
||||
|
||||
@gen.coroutine
|
||||
def upload_from_stream_with_id():
|
||||
async def upload_from_stream_with_id():
|
||||
my_db = MotorClient().test
|
||||
fs = MotorGridFSBucket(my_db)
|
||||
file_id = yield fs.upload_from_stream_with_id(
|
||||
file_id = await fs.upload_from_stream_with_id(
|
||||
ObjectId(),
|
||||
"test_file",
|
||||
b"data I want to store!",
|
||||
|
||||
@ -34,18 +34,18 @@
|
||||
To create a single key ascending index on the key ``'mike'`` we just
|
||||
use a string argument::
|
||||
|
||||
yield my_collection.create_index("mike")
|
||||
await my_collection.create_index("mike")
|
||||
|
||||
For a compound index on ``'mike'`` descending and ``'eliot'``
|
||||
ascending we need to use a list of tuples::
|
||||
|
||||
yield my_collection.create_index([("mike", pymongo.DESCENDING),
|
||||
await my_collection.create_index([("mike", pymongo.DESCENDING),
|
||||
("eliot", pymongo.ASCENDING)])
|
||||
|
||||
All optional index creation parameters should be passed as
|
||||
keyword arguments to this method. For example::
|
||||
|
||||
yield my_collection.create_index([("mike", pymongo.DESCENDING)],
|
||||
await my_collection.create_index([("mike", pymongo.DESCENDING)],
|
||||
background=True)
|
||||
|
||||
Valid options include, but are not limited to:
|
||||
@ -122,7 +122,7 @@
|
||||
`map reduce command`_ may be passed as keyword arguments to this
|
||||
helper method, e.g.::
|
||||
|
||||
yield db.test.inline_map_reduce(map, reduce, limit=2)
|
||||
await db.test.inline_map_reduce(map, reduce, limit=2)
|
||||
|
||||
Returns a Future.
|
||||
|
||||
|
||||
@ -64,14 +64,13 @@ GridFS
|
||||
Updating metadata on a :class:`MotorGridIn` is asynchronous, so
|
||||
the API is different::
|
||||
|
||||
@gen.coroutine
|
||||
def f():
|
||||
async def f():
|
||||
fs = motor.motor_tornado.MotorGridFSBucket(db)
|
||||
grid_in, file_id = fs.open_upload_stream('test_file')
|
||||
yield grid_in.close()
|
||||
await grid_in.close()
|
||||
|
||||
# Sends update to server.
|
||||
yield grid_in.set('my_field', 'my_value')
|
||||
await grid_in.set('my_field', 'my_value')
|
||||
|
||||
.. seealso:: :doc:`../api-tornado/gridfs`.
|
||||
|
||||
@ -83,7 +82,7 @@ In PyMongo ``is_locked`` is a property of
|
||||
server has been fsyncLocked requires I/O, Motor has no such convenience method.
|
||||
The equivalent in Motor is::
|
||||
|
||||
result = yield client.admin.current_op()
|
||||
result = await client.admin.current_op()
|
||||
locked = bool(result.get('fsyncLock', None))
|
||||
|
||||
system_js
|
||||
@ -119,7 +118,7 @@ In Motor, however, no exception is raised. The query simply has no results:
|
||||
|
||||
# Iterates zero or one times.
|
||||
async for doc in cursor:
|
||||
pass
|
||||
print(doc)
|
||||
|
||||
The difference arises because the PyMongo :class:`~pymongo.cursor.Cursor`'s
|
||||
slicing operator blocks until it has queried the MongoDB server, and determines
|
||||
@ -151,9 +150,8 @@ only the typical style is allowed:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@gen.coroutine
|
||||
def f():
|
||||
yield db.create_collection(
|
||||
async def f():
|
||||
await db.create_collection(
|
||||
'collection1',
|
||||
capped=True,
|
||||
size=1000)
|
||||
|
||||
@ -30,10 +30,9 @@ bulk insert operations.
|
||||
|
||||
.. doctest::
|
||||
|
||||
>>> @gen.coroutine
|
||||
... def f():
|
||||
... yield db.test.insert_many(({'i': i} for i in range(10000)))
|
||||
... count = yield db.test.count_documents({})
|
||||
>>> async def f():
|
||||
... await db.test.insert_many(({'i': i} for i in range(10000)))
|
||||
... count = await db.test.count_documents({})
|
||||
... print("Final count: %d" % count)
|
||||
>>>
|
||||
>>> IOLoop.current().run_sync(f)
|
||||
@ -61,9 +60,8 @@ of operations performed.
|
||||
|
||||
>>> from pprint import pprint
|
||||
>>> from pymongo import InsertOne, DeleteMany, ReplaceOne, UpdateOne
|
||||
>>> @gen.coroutine
|
||||
... def f():
|
||||
... result = yield db.test.bulk_write([
|
||||
>>> async def f():
|
||||
... result = await db.test.bulk_write([
|
||||
... DeleteMany({}), # Remove all documents from the previous example.
|
||||
... InsertOne({'_id': 1}),
|
||||
... InsertOne({'_id': 2}),
|
||||
@ -95,14 +93,13 @@ the failure.
|
||||
|
||||
>>> from pymongo import InsertOne, DeleteOne, ReplaceOne
|
||||
>>> from pymongo.errors import BulkWriteError
|
||||
>>> @gen.coroutine
|
||||
... def f():
|
||||
>>> async def f():
|
||||
... requests = [
|
||||
... ReplaceOne({'j': 2}, {'i': 5}),
|
||||
... InsertOne({'_id': 4}), # Violates the unique key constraint on _id.
|
||||
... DeleteOne({'i': 5})]
|
||||
... try:
|
||||
... yield db.test.bulk_write(requests)
|
||||
... await db.test.bulk_write(requests)
|
||||
... except BulkWriteError as bwe:
|
||||
... pprint(bwe.details)
|
||||
...
|
||||
@ -135,15 +132,14 @@ and fourth operations succeed.
|
||||
.. doctest::
|
||||
:options: +NORMALIZE_WHITESPACE
|
||||
|
||||
>>> @gen.coroutine
|
||||
... def f():
|
||||
>>> async def f():
|
||||
... requests = [
|
||||
... InsertOne({'_id': 1}),
|
||||
... DeleteOne({'_id': 2}),
|
||||
... InsertOne({'_id': 3}),
|
||||
... ReplaceOne({'_id': 4}, {'i': 1})]
|
||||
... try:
|
||||
... yield db.test.bulk_write(requests, ordered=False)
|
||||
... await db.test.bulk_write(requests, ordered=False)
|
||||
... except BulkWriteError as bwe:
|
||||
... pprint(bwe.details)
|
||||
...
|
||||
@ -178,12 +174,11 @@ after all operations are attempted, regardless of execution order.
|
||||
.. Standalone MongoDB raises "can't use w>1" with this example, so skip it.
|
||||
|
||||
>>> from pymongo import WriteConcern
|
||||
>>> @gen.coroutine
|
||||
... def f():
|
||||
>>> async def f():
|
||||
... coll = db.get_collection(
|
||||
... 'test', write_concern=WriteConcern(w=4, wtimeout=1))
|
||||
... try:
|
||||
... yield coll.bulk_write([InsertOne({'a': i}) for i in range(4)])
|
||||
... await coll.bulk_write([InsertOne({'a': i}) for i in range(4)])
|
||||
... except BulkWriteError as bwe:
|
||||
... pprint(bwe.details)
|
||||
...
|
||||
|
||||
@ -129,7 +129,7 @@ def get_motor_attr(motor_class, name, *defargs):
|
||||
attribute. While we're at it, store some info about each attribute
|
||||
in the global motor_info dict.
|
||||
"""
|
||||
attr = safe_getattr(motor_class, name)
|
||||
attr = safe_getattr(motor_class, name, *defargs)
|
||||
|
||||
# Store some info for process_motor_nodes()
|
||||
full_name = '%s.%s.%s' % (
|
||||
|
||||
@ -547,16 +547,9 @@ class AgnosticDatabase(AgnosticBaseProperties):
|
||||
Returns a :class:`MotorCommandCursor` that can be iterated like a
|
||||
cursor from :meth:`find`::
|
||||
|
||||
# Lists all operations currently running on the server.
|
||||
pipeline = [{"$currentOp": {}}]
|
||||
cursor = client.admin.aggregate(pipeline)
|
||||
async for operation in cursor:
|
||||
print(operation)
|
||||
|
||||
In Python 3.5 and newer, aggregation cursors can be iterated elegantly
|
||||
in native coroutines with `async for`::
|
||||
|
||||
async def f():
|
||||
# Lists all operations currently running on the server.
|
||||
pipeline = [{"$currentOp": {}}]
|
||||
async for operation in client.admin.aggregate(pipeline):
|
||||
print(operation)
|
||||
|
||||
@ -832,15 +825,8 @@ class AgnosticCollection(AgnosticBaseProperties):
|
||||
Returns a :class:`MotorCommandCursor` that can be iterated like a
|
||||
cursor from :meth:`find`::
|
||||
|
||||
pipeline = [{'$project': {'name': {'$toUpper': '$name'}}}]
|
||||
cursor = collection.aggregate(pipeline)
|
||||
async for doc in cursor:
|
||||
print(doc)
|
||||
|
||||
In Python 3.5 and newer, aggregation cursors can be iterated elegantly
|
||||
in native coroutines with `async for`::
|
||||
|
||||
async def f():
|
||||
pipeline = [{'$project': {'name': {'$toUpper': '$name'}}}]
|
||||
async for doc in collection.aggregate(pipeline):
|
||||
print(doc)
|
||||
|
||||
@ -1104,10 +1090,10 @@ class AgnosticBaseCursor(AgnosticBase):
|
||||
|
||||
.. note::
|
||||
There is no need to manually close cursors; they are closed
|
||||
by the server after being fully iterated using `async for`,
|
||||
:meth:`to_list`, or :meth:`each`, or automatically closed
|
||||
by the client when the :class:`MotorCursor` is cleaned up by
|
||||
the garbage collector.
|
||||
by the server after being fully iterated
|
||||
with :meth:`to_list`, :meth:`each`, or `async for`, or
|
||||
automatically closed by the client when the :class:`MotorCursor` is
|
||||
cleaned up by the garbage collector.
|
||||
"""
|
||||
# 'cursor' is a PyMongo Cursor, CommandCursor, or a _LatentCursor.
|
||||
super(AgnosticBaseCursor, self).__init__(delegate=cursor)
|
||||
@ -1171,6 +1157,10 @@ class AgnosticBaseCursor(AgnosticBase):
|
||||
>>> IOLoop.current().run_sync(f)
|
||||
0, 1, 2, 3, 4, done
|
||||
|
||||
While it appears that fetch_next retrieves each document from
|
||||
the server individually, the cursor actually fetches documents
|
||||
efficiently in `large batches`_. Example usage:
|
||||
|
||||
.. doctest:: fetch_next
|
||||
|
||||
>>> async def f():
|
||||
@ -1185,10 +1175,6 @@ class AgnosticBaseCursor(AgnosticBase):
|
||||
>>> IOLoop.current().run_sync(f)
|
||||
0, 1, 2, 3, 4, done
|
||||
|
||||
While it appears that fetch_next retrieves each document from
|
||||
the server individually, the cursor actually fetches documents
|
||||
efficiently in `large batches`_.
|
||||
|
||||
.. versionchanged:: 2.2
|
||||
Deprecated.
|
||||
|
||||
@ -1271,8 +1257,7 @@ class AgnosticBaseCursor(AgnosticBase):
|
||||
|
||||
.. note:: Unlike other Motor methods, ``each`` requires a callback and
|
||||
does not return a Future, so it cannot be used in a coroutine.
|
||||
``async for``, :meth:`to_list`, :attr:`fetch_next` are much easier to
|
||||
use.
|
||||
``async for`` and :meth:`to_list` are much easier to use.
|
||||
|
||||
:Parameters:
|
||||
- `callback`: function taking (document, error)
|
||||
@ -1582,13 +1567,13 @@ class AgnosticLatentCommandCursor(AgnosticCommandCursor):
|
||||
__motor_class_name__ = 'MotorLatentCommandCursor'
|
||||
|
||||
def __init__(self, collection, start, *args, **kwargs):
|
||||
# We're being constructed without yield or await, like:
|
||||
# We're being constructed without await, like:
|
||||
#
|
||||
# cursor = collection.aggregate(pipeline)
|
||||
#
|
||||
# ... so we can't send the "aggregate" command to the server and get
|
||||
# a PyMongo CommandCursor back yet. Set self.delegate to a latent
|
||||
# cursor until the first yield or await triggers _get_more(), which
|
||||
# cursor until the first await triggers _get_more(), which
|
||||
# will execute the callback "start", which gets a PyMongo CommandCursor.
|
||||
super(self.__class__, self).__init__(_LatentCursor(), collection)
|
||||
self.start = start
|
||||
|
||||
Loading…
Reference in New Issue
Block a user