Motor 2 migration guide
This commit is contained in:
parent
226c98df6a
commit
a5a00a6357
@ -9,6 +9,8 @@ Motor 1.3.0
|
||||
Deprecate Motor's old callback-based async API in preparation for removing it in
|
||||
Motor 2.0. Raise ``DeprecationWarning`` whenever a callback is passed.
|
||||
|
||||
See the :doc:`migrate-to-motor-2`.
|
||||
|
||||
Motor 1.2.3
|
||||
-----------
|
||||
|
||||
@ -143,7 +145,7 @@ Motor 1.0
|
||||
---------
|
||||
|
||||
Motor now depends on PyMongo 3.3 and later. The move from PyMongo 2 to 3 brings
|
||||
a large number of API changes, read :doc:`migrate-to-motor-1` and
|
||||
a large number of API changes, read
|
||||
`the PyMongo 3 changelog`_ carefully.
|
||||
|
||||
.. _the PyMongo 3 changelog: http://api.mongodb.com/python/current/changelog.html#changes-in-version-3-0
|
||||
@ -354,8 +356,7 @@ This version updates the PyMongo dependency from 2.8.0 to 2.9.x, and wraps
|
||||
PyMongo 2.9's new APIs.
|
||||
|
||||
Most of Motor 1.0's API is now implemented, and APIs that will be removed in
|
||||
Motor 1.0 are now deprecated and raise warnings. See the
|
||||
:doc:`/migrate-to-motor-1` to prepare your code for Motor 1.0.
|
||||
Motor 1.0 are now deprecated and raise warnings.
|
||||
|
||||
:class:`MotorClient` changes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -62,7 +62,7 @@ Contents
|
||||
tutorial-asyncio
|
||||
examples/index
|
||||
changelog
|
||||
migrate-to-motor-1
|
||||
migrate-to-motor-2
|
||||
developer-guide
|
||||
contributors
|
||||
|
||||
|
||||
@ -1,400 +0,0 @@
|
||||
Motor 1.0 Migration Guide
|
||||
=========================
|
||||
|
||||
.. currentmodule:: motor.motor_tornado
|
||||
|
||||
Motor 1.0 brings a number of backward breaking changes to the pre-1.0 API.
|
||||
Follow this guide to migrate an existing application that had used an older
|
||||
version of Motor.
|
||||
|
||||
Removed features with no migration path
|
||||
---------------------------------------
|
||||
|
||||
:class:`MotorReplicaSetClient` is removed
|
||||
..........................................
|
||||
|
||||
In Motor 1.0, :class:`MotorClient` is the only class. Connect to a replica set with
|
||||
a "replicaSet" URI option or parameter::
|
||||
|
||||
MotorClient("mongodb://localhost/?replicaSet=my-rs")
|
||||
MotorClient(host, port, replicaSet="my-rs")
|
||||
|
||||
The "compile_re" option is removed
|
||||
..................................
|
||||
|
||||
In Motor 1.0 regular expressions are never compiled to Python `re.match`
|
||||
objects.
|
||||
|
||||
Motor 0.7
|
||||
---------
|
||||
|
||||
The first step in migrating to Motor 1.0 is to upgrade to at least Motor 0.7.
|
||||
If your project has a
|
||||
requirements.txt file, add the line::
|
||||
|
||||
motor >= 0.7, < 1.0
|
||||
|
||||
Most of the key new
|
||||
methods and options from Motor 1.0 are backported in Motor 0.7 making
|
||||
migration much easier.
|
||||
|
||||
Enable Deprecation Warnings
|
||||
---------------------------
|
||||
|
||||
Starting with Motor 0.7, :exc:`DeprecationWarning` is raised by most methods
|
||||
removed in Motor 1.0. Make sure you enable runtime warnings to see
|
||||
where deprecated functions and methods are being used in your application::
|
||||
|
||||
python -Wd <your application>
|
||||
|
||||
Warnings can also be changed to errors::
|
||||
|
||||
python -Wd -Werror <your application>
|
||||
|
||||
Not all deprecated features raise `DeprecationWarning` when
|
||||
used. For example, `~motor.motor_tornado.MotorReplicaSetClient` will be
|
||||
removed in Motor 1.0 but it does not raise `DeprecationWarning`
|
||||
in Motor 0.7. See also `Removed features with no migration path`_.
|
||||
|
||||
CRUD API
|
||||
--------
|
||||
|
||||
Changes to find() and find_one()
|
||||
................................
|
||||
|
||||
"spec" renamed "filter"
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``spec`` option has been renamed to ``filter``. Code like this::
|
||||
|
||||
cursor = collection.find(spec={"a": 1})
|
||||
|
||||
can be changed to this with Motor 0.7 or later::
|
||||
|
||||
cursor = collection.find(filter={"a": 1})
|
||||
|
||||
or this with any version of Motor::
|
||||
|
||||
cursor = collection.find({"a": 1})
|
||||
|
||||
"fields" renamed "projection"
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``fields`` option has been renamed to ``projection``. Code like this::
|
||||
|
||||
cursor = collection.find({"a": 1}, fields={"_id": False})
|
||||
|
||||
can be changed to this with Motor 0.7 or later::
|
||||
|
||||
cursor = collection.find({"a": 1}, projection={"_id": False})
|
||||
|
||||
or this with any version of Motor::
|
||||
|
||||
cursor = collection.find({"a": 1}, {"_id": False})
|
||||
|
||||
"partial" renamed "allow_partial_results"
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``partial`` option has been renamed to ``allow_partial_results``. Code like
|
||||
this::
|
||||
|
||||
cursor = collection.find({"a": 1}, partial=True)
|
||||
|
||||
can be changed to this with Motor 0.7 or later::
|
||||
|
||||
cursor = collection.find({"a": 1}, allow_partial_results=True)
|
||||
|
||||
"timeout" replaced by "no_cursor_timeout"
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``timeout`` option has been replaced by ``no_cursor_timeout``. Code like this::
|
||||
|
||||
cursor = collection.find({"a": 1}, timeout=False)
|
||||
|
||||
can be changed to this with Motor 0.7 or later::
|
||||
|
||||
cursor = collection.find({"a": 1}, no_cursor_timeout=True)
|
||||
|
||||
"snapshot" and "max_scan" replaced by "modifiers"
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``snapshot`` and ``max_scan`` options have been removed. They can now be set,
|
||||
along with other $ query modifiers, through the ``modifiers`` option. Code like
|
||||
this::
|
||||
|
||||
cursor = collection.find({"a": 1}, snapshot=True)
|
||||
|
||||
can be changed to this with Motor 0.7 or later::
|
||||
|
||||
cursor = collection.find({"a": 1}, modifiers={"$snapshot": True})
|
||||
|
||||
or with any version of Motor::
|
||||
|
||||
cursor = collection.find({"$query": {"a": 1}, "$snapshot": True})
|
||||
|
||||
"network_timeout" is removed
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``network_timeout`` option has been removed. This option was always the
|
||||
wrong solution for timing out long running queries and should never be used
|
||||
in production. Starting with **MongoDB 2.6** you can use the $maxTimeMS query
|
||||
modifier. Code like this::
|
||||
|
||||
# Set a 5 second select() timeout.
|
||||
cursor = collection.find({"a": 1}, network_timeout=5)
|
||||
|
||||
can be changed to this with Motor 0.7 or later::
|
||||
|
||||
# Set a 5 second (5000 millisecond) server side query timeout.
|
||||
cursor = collection.find({"a": 1}, modifiers={"$maxTimeMS": 5000})
|
||||
|
||||
or with any version of Motor::
|
||||
|
||||
cursor = collection.find({"$query": {"a": 1}, "$maxTimeMS": 5000})
|
||||
|
||||
.. seealso:: `$maxTimeMS
|
||||
<http://docs.mongodb.org/manual/reference/operator/meta/maxTimeMS/>`_
|
||||
|
||||
Tailable cursors
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``tailable`` and ``await_data`` options have been replaced by ``cursor_type``.
|
||||
Code like this::
|
||||
|
||||
cursor = collection.find({"a": 1}, tailable=True)
|
||||
cursor = collection.find({"a": 1}, tailable=True, await_data=True)
|
||||
|
||||
can be changed to this with Motor 0.7 or later::
|
||||
|
||||
from pymongo import CursorType
|
||||
cursor = collection.find({"a": 1}, cursor_type=CursorType.TAILABLE)
|
||||
cursor = collection.find({"a": 1}, cursor_type=CursorType.TAILABLE_AWAIT)
|
||||
|
||||
Other removed options
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``read_preference``, ``tag_sets``,
|
||||
and ``secondary_acceptable_latency_ms`` options have been removed. See the `Read
|
||||
Preferences`_ section for solutions.
|
||||
|
||||
Read Preferences
|
||||
----------------
|
||||
|
||||
The "read_preference" attribute is immutable
|
||||
............................................
|
||||
|
||||
Code like this::
|
||||
|
||||
from pymongo import ReadPreference
|
||||
db = client.my_database
|
||||
db.read_preference = ReadPreference.SECONDARY
|
||||
|
||||
can be changed to this with Motor 0.7 or later::
|
||||
|
||||
db = client.get_database("my_database",
|
||||
read_preference=ReadPreference.SECONDARY)
|
||||
|
||||
Code like this::
|
||||
|
||||
cursor = collection.find({"a": 1},
|
||||
read_preference=ReadPreference.SECONDARY)
|
||||
|
||||
can be changed to this with Motor 0.7 or later::
|
||||
|
||||
coll2 = collection.with_options(read_preference=ReadPreference.SECONDARY)
|
||||
cursor = coll2.find({"a": 1})
|
||||
|
||||
.. seealso:: :meth:`~MotorDatabase.get_collection`
|
||||
|
||||
The "tag_sets" option and attribute are removed
|
||||
...............................................
|
||||
|
||||
The ``tag_sets`` MotorClient option is removed. The ``read_preference``
|
||||
option can be used instead. Code like this::
|
||||
|
||||
client = MotorClient(
|
||||
read_preference=ReadPreference.SECONDARY,
|
||||
tag_sets=[{"dc": "ny"}, {"dc": "sf"}])
|
||||
|
||||
can be changed to this with Motor 0.7 or later::
|
||||
|
||||
from pymongo.read_preferences import Secondary
|
||||
client = MotorClient(read_preference=Secondary([{"dc": "ny"}]))
|
||||
|
||||
To change the tags sets for a MotorDatabase or MotorCollection, code like this::
|
||||
|
||||
db = client.my_database
|
||||
db.read_preference = ReadPreference.SECONDARY
|
||||
db.tag_sets = [{"dc": "ny"}]
|
||||
|
||||
can be changed to this with Motor 0.7 or later::
|
||||
|
||||
db = client.get_database("my_database",
|
||||
read_preference=Secondary([{"dc": "ny"}]))
|
||||
|
||||
Code like this::
|
||||
|
||||
cursor = collection.find(
|
||||
{"a": 1},
|
||||
read_preference=ReadPreference.SECONDARY,
|
||||
tag_sets=[{"dc": "ny"}])
|
||||
|
||||
can be changed to this with Motor 0.7 or later::
|
||||
|
||||
from pymongo.read_preferences import Secondary
|
||||
coll2 = collection.with_options(
|
||||
read_preference=Secondary([{"dc": "ny"}]))
|
||||
cursor = coll2.find({"a": 1})
|
||||
|
||||
.. seealso:: :meth:`~MotorDatabase.get_collection`
|
||||
|
||||
The "secondary_acceptable_latency_ms" option and attribute are removed
|
||||
......................................................................
|
||||
|
||||
Motor 0.x supports ``secondary_acceptable_latency_ms`` as an option to methods
|
||||
throughout the driver, but mongos only supports a global latency option.
|
||||
Motor 1.0 has changed to match the behavior of mongos, allowing migration
|
||||
from a single server, to a replica set, to a sharded cluster without a
|
||||
surprising change in server selection behavior. A new option,
|
||||
``localThresholdMS``, is available through MotorClient and should be used in
|
||||
place of ``secondaryAcceptableLatencyMS``. Code like this::
|
||||
|
||||
client = MotorClient(readPreference="nearest",
|
||||
secondaryAcceptableLatencyMS=100)
|
||||
|
||||
can be changed to this with Motor 0.7 or later::
|
||||
|
||||
client = MotorClient(readPreference="nearest",
|
||||
localThresholdMS=100)
|
||||
|
||||
Write Concern
|
||||
-------------
|
||||
|
||||
The "write_concern" attribute is immutable
|
||||
..........................................
|
||||
|
||||
The ``write_concern`` attribute is immutable in Motor 1.0. Code like this::
|
||||
|
||||
client = MotorClient()
|
||||
client.write_concern = {"w": "majority"}
|
||||
|
||||
can be changed to this with any version of Motor::
|
||||
|
||||
client = MotorClient(w="majority")
|
||||
|
||||
Code like this::
|
||||
|
||||
db = client.my_database
|
||||
db.write_concern = {"w": "majority"}
|
||||
|
||||
can be changed to this with Motor 0.7 or later::
|
||||
|
||||
from pymongo import WriteConcern
|
||||
db = client.get_database("my_database",
|
||||
write_concern=WriteConcern(w="majority"))
|
||||
|
||||
The new CRUD API write methods do not accept write concern options. Code like
|
||||
this::
|
||||
|
||||
oid = collection.insert({"a": 2}, w="majority")
|
||||
|
||||
can be changed to this with Motor 0.7 or later::
|
||||
|
||||
from pymongo import WriteConcern
|
||||
coll2 = collection.with_options(
|
||||
write_concern=WriteConcern(w="majority"))
|
||||
oid = coll2.insert({"a": 2})
|
||||
|
||||
.. seealso:: :meth:`~MotorDatabase.get_collection`
|
||||
|
||||
Codec Options
|
||||
-------------
|
||||
|
||||
The "document_class" attribute is removed
|
||||
.........................................
|
||||
|
||||
Code like this::
|
||||
|
||||
from bson.son import SON
|
||||
client = MotorClient()
|
||||
client.document_class = SON
|
||||
|
||||
can be replaced by this in any version of Motor::
|
||||
|
||||
from bson.son import SON
|
||||
client = MotorClient(document_class=SON)
|
||||
|
||||
or to change the ``document_class`` for a :class:`MotorDatabase`
|
||||
with Motor 0.7 or later::
|
||||
|
||||
from bson.codec_options import CodecOptions
|
||||
from bson.son import SON
|
||||
db = client.get_database("my_database", CodecOptions(SON))
|
||||
|
||||
.. seealso:: :meth:`~MotorDatabase.get_collection` and
|
||||
:meth:`~MotorCollection.with_options`
|
||||
|
||||
The "uuid_subtype" option and attribute are removed
|
||||
...................................................
|
||||
|
||||
Code like this::
|
||||
|
||||
from bson.binary import JAVA_LEGACY
|
||||
db = client.my_database
|
||||
db.uuid_subtype = JAVA_LEGACY
|
||||
|
||||
can be replaced by this with Motor 0.7 or later::
|
||||
|
||||
from bson.binary import JAVA_LEGACY
|
||||
from bson.codec_options import CodecOptions
|
||||
db = client.get_database("my_database",
|
||||
CodecOptions(uuid_representation=JAVA_LEGACY))
|
||||
|
||||
.. seealso:: :meth:`~MotorDatabase.get_collection` and
|
||||
:meth:`~MotorCollection.with_options`
|
||||
|
||||
MotorClient
|
||||
-----------
|
||||
|
||||
The ``open`` method
|
||||
...................
|
||||
|
||||
The :meth:`~MotorClient.open` method is removed in Motor 1.0.
|
||||
Motor clients have opened themselves on demand since Motor 0.2.
|
||||
|
||||
The max_pool_size parameter is removed
|
||||
......................................
|
||||
|
||||
Motor 1.0 replaced the max_pool_size parameter with support for the MongoDB URI
|
||||
``maxPoolSize`` option. Code like this::
|
||||
|
||||
client = MotorClient(max_pool_size=10)
|
||||
|
||||
can be replaced by this with Motor 0.7 or later::
|
||||
|
||||
client = MotorClient(maxPoolSize=10)
|
||||
client = MotorClient("mongodb://localhost:27017/?maxPoolSize=10")
|
||||
|
||||
The "disconnect" method is removed
|
||||
..................................
|
||||
|
||||
Code like this::
|
||||
|
||||
client.disconnect()
|
||||
|
||||
can be replaced by this::
|
||||
|
||||
client.close()
|
||||
|
||||
The host and port attributes are removed
|
||||
........................................
|
||||
|
||||
Code like this::
|
||||
|
||||
host = client.host
|
||||
port = client.port
|
||||
|
||||
can be replaced by this with Motor 0.7 or later::
|
||||
|
||||
address = client.address
|
||||
host, port = address or (None, None)
|
||||
206
doc/migrate-to-motor-2.rst
Normal file
206
doc/migrate-to-motor-2.rst
Normal file
@ -0,0 +1,206 @@
|
||||
Motor 2.0 Migration Guide
|
||||
=========================
|
||||
|
||||
.. currentmodule:: motor.motor_tornado
|
||||
|
||||
Motor 2.0 brings a number of changes to Motor 1.0's API. The major version is
|
||||
required in order to update the session API to support multi-document
|
||||
transactions, introduced in MongoDB 4.0; this feature is so valuable that it
|
||||
motivated me to make the breaking change and bump the version number to 2.0.
|
||||
Since this is the first major version number in almost two years, it removes a
|
||||
large number of APIs that have been deprecated in the time since Motor 1.0.
|
||||
|
||||
Follow this guide to migrate an existing application that had used Motor 1.x.
|
||||
|
||||
Check compatibility
|
||||
-------------------
|
||||
|
||||
Read the :doc:`requirements` page and ensure your MongoDB server and Python
|
||||
interpreter are compatible, and your Tornado version if you are using Tornado.
|
||||
If you use aiohttp, upgrade to at least 3.0.
|
||||
|
||||
Upgrade to Motor 1.3
|
||||
--------------------
|
||||
|
||||
The first step in migrating to Motor 2.0 is to upgrade to at least Motor 1.3.
|
||||
If your project has a
|
||||
requirements.txt file, add the line::
|
||||
|
||||
motor >= 1.3, < 2.0
|
||||
|
||||
Enable Deprecation Warnings
|
||||
---------------------------
|
||||
|
||||
Starting with Motor 1.3, :exc:`DeprecationWarning` is raised by most methods
|
||||
removed in Motor 2.0. Make sure you enable runtime warnings to see where
|
||||
deprecated functions and methods are being used in your application::
|
||||
|
||||
python -Wd <your application>
|
||||
|
||||
Warnings can also be changed to errors::
|
||||
|
||||
python -Wd -Werror <your application>
|
||||
|
||||
Migrate from deprecated APIs
|
||||
----------------------------
|
||||
|
||||
The following features are deprecated by PyMongo and scheduled for removal;
|
||||
they are now deleted from Motor:
|
||||
|
||||
- ``MotorClient.kill_cursors`` and ``close_cursor``.
|
||||
Allow :class:`MotorCursor` to handle its own cleanup.
|
||||
- ``MotorClient.get_default_database``. Call :meth:`MotorClient.get_database`
|
||||
with a database name of ``None`` for the same effect.
|
||||
- ``MotorDatabase.add_son_manipulator``. Transform documents to and from
|
||||
their MongoDB representations in your application code instead.
|
||||
|
||||
- The server command ``getLastError`` and related commands are deprecated,
|
||||
their helper functions are deleted from Motor:
|
||||
|
||||
- ``MotorDatabase.last_status``
|
||||
- ``MotorDatabase.error``
|
||||
- ``MotorDatabase.previous_error``
|
||||
- ``MotorDatabase.reset_error_history``
|
||||
|
||||
Use acknowledged writes and rely on Motor to raise exceptions.
|
||||
|
||||
- The server command ``parallelCollectionScan`` is deprecated and
|
||||
``MotorCollection.parallel_scan`` is removed. Use a regular
|
||||
:meth:`MotorCollection.find` cursor.
|
||||
- ``MotorClient.database_names``. Use
|
||||
:meth:`~MotorClient.list_database_names`.
|
||||
- ``MotorDatabase.eval``. The server command is deprecated but
|
||||
still available with ``MotorDatabase.command("eval", ...)``.
|
||||
- ``MotorDatabase.group``. The server command is deprecated but
|
||||
still available with ``MotorDatabase.command("group", ...)``.
|
||||
- ``MotorDatabase.authenticate`` and ``MotorDatabase.logout``. Add credentials
|
||||
to the URI or ``MotorClient`` options instead of calling ``authenticate``.
|
||||
To authenticate as multiple users on the same database, instead of using
|
||||
``authenticate`` and ``logout`` use a separate client for each user.
|
||||
- ``MotorCollection.initialize_unordered_bulk_op``,
|
||||
``initialize_unordered_bulk_op``, and ``MotorBulkOperationBuilder``. Use
|
||||
:meth:`MotorCollection.bulk_write``, see :ref:`Bulk Writes Tutorial
|
||||
<bulk-write-tutorial>`.
|
||||
- ``MotorCollection.count``. Use :meth:`~MotorCollection.count_documents` or
|
||||
:meth:`~MotorCollection.estimated_document_count`.
|
||||
- ``MotorCollection.ensure_index``. Use
|
||||
:meth:`MotorCollection.create_indexes`.
|
||||
- Deprecated write methods have been deleted from :class:`MotorCollection`.
|
||||
|
||||
- ``save`` and ``insert``: Use :meth:`~MotorCollection.insert_one` or
|
||||
:meth:`~MotorCollection.insert_many`.
|
||||
- ``update``: Use :meth:`~MotorCollection.update_one`,
|
||||
:meth:`~MotorCollection.update_many`, or
|
||||
:meth:`~MotorCollection.replace_one`.
|
||||
- ``remove``: Use :meth:`~MotorCollection.delete_one` or
|
||||
:meth:`~MotorCollection.delete_many`.
|
||||
- ``find_and_modify``: Use :meth:`~MotorCollection.find_one_and_update`,
|
||||
:meth:`~MotorCollection.find_one_and_replace`, or
|
||||
:meth:`~MotorCollection.find_one_and_delete`.
|
||||
|
||||
- ``MotorCursor.count`` and ``MotorGridOutCursor.count``. Use
|
||||
:meth:`MotorCollection.count_documents` or
|
||||
:meth:`MotorCollection.estimated_document_count`.
|
||||
|
||||
Migrate from the original callback API
|
||||
--------------------------------------
|
||||
|
||||
Motor was first released before Tornado had introduced Futures, generator-based
|
||||
coroutines, and the ``yield`` syntax, and long before the async features
|
||||
developed during Python 3's career. Therefore Motor's original asynchronous API
|
||||
used callbacks:
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
def callback(result, error):
|
||||
if error:
|
||||
print(error)
|
||||
else:
|
||||
print(result)
|
||||
|
||||
collection.find_one({}, callback=callback)
|
||||
|
||||
Callbacks have been largely superseded by a Futures API intended for use with
|
||||
coroutines, see :doc:`tutorial-tornado`. You can still use callbacks with Motor when
|
||||
appropriate but you must add the callback to a Future instead of passing it as
|
||||
a parameter:
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
def callback(future):
|
||||
try:
|
||||
result = future.result()
|
||||
print(result)
|
||||
except Exception as exc:
|
||||
print(exc)
|
||||
|
||||
future = collection.find_one({})
|
||||
future.add_done_callback(callback)
|
||||
|
||||
The :meth:`~asyncio.Future.add_done_callback` call can be placed on the same
|
||||
line:
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
collection.find_one({}).add_done_callback(callback)
|
||||
|
||||
In almost all cases the modern coroutine API is more readable and provides
|
||||
better exception handling:
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
async def do_find():
|
||||
try:
|
||||
result = await collection.find_one({})
|
||||
print(result)
|
||||
except Exception as exc:
|
||||
print(exc)
|
||||
|
||||
Upgrade to Motor 2.0
|
||||
--------------------
|
||||
|
||||
Once your application runs without deprecation warnings with Motor 1.3, upgrade
|
||||
to Motor 2.0. Update any calls in your code to
|
||||
:meth:`MotorClient.start_session` or
|
||||
:meth:`~pymongo.client_session.ClientSession.end_session` to handle the
|
||||
following change.
|
||||
|
||||
:meth:`MotorClient.start_session` is a coroutine
|
||||
------------------------------------------------
|
||||
|
||||
In the past, you could use a client session like:
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
session = client.start_session()
|
||||
doc = await client.db.collection.find_one({}, session=session)
|
||||
session.end_session()
|
||||
|
||||
Or:
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
with client.start_session() as session:
|
||||
doc = client.db.collection.find_one({}, session=session)
|
||||
|
||||
To support multi-document transactions, in Motor 2.0
|
||||
:meth:`MotorClient.start_session` is a coroutine, not a regular method. It must
|
||||
be used like ``await client.start_session()`` or ``async with await
|
||||
client.start_session()``. The coroutine now returns a new class
|
||||
:class:`~motor.motor_tornado.MotorClientSession`, not PyMongo's
|
||||
:class:`~pymongo.client_session.ClientSession`. The ``end_session`` method on
|
||||
the returned :class:`~motor.motor_tornado.MotorClientSession` is also now a
|
||||
coroutine instead of a regular method. Use it like:
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
session = await client.start_session()
|
||||
doc = await client.db.collection.find_one({}, session=session)
|
||||
await session.end_session()
|
||||
|
||||
Or:
|
||||
|
||||
.. code-block:: python3
|
||||
|
||||
async with client.start_session() as session:
|
||||
doc = await client.db.collection.find_one({}, session=session)
|
||||
Loading…
Reference in New Issue
Block a user