@@ -18,20 +18,29 @@ Migrate to {+driver-async+}
18
18
.. meta::
19
19
:keywords: motor, async, refactor, migration, asynchronous
20
20
21
- .. include:: /includes/pymongo-async-experimental.rst
22
-
23
21
Overview
24
22
--------
25
23
26
- The {+driver-async+} driver is a unification of {+driver-short+} and the `Motor
24
+ The {+driver-async+} API is a unification of {+driver-short+} and the `Motor
27
25
library <https://www.mongodb.com/docs/drivers/motor/>`__. In this guide, you can
28
26
identify the changes you must make to migrate an application from {+driver-short+} or
29
- Motor to the {+driver-async+} driver.
27
+ Motor to the {+driver-async+} API.
28
+
29
+ Motivation
30
+ ~~~~~~~~~~
31
+
32
+ The {+driver-async+} API is designed to be a replacement for the Motor
33
+ library. Motor was created to provide support for Tornado, with asyncio support
34
+ added later. Because of this, Motor provides full asyncio and Tornado support,
35
+ but still relies on a thread pool to perform network operations. In some cases,
36
+ this might lead to performance degradation when using the Motor library. To
37
+ address this issue, the {+driver-async+} API includes asyncio support directly
38
+ into {+driver-short+}.
30
39
31
40
Synchronous Versus Asynchronous
32
41
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33
42
34
- To determine whether to migrate to the {+driver-async+} driver or to continue using
43
+ To determine whether to migrate to the {+driver-async+} API or to continue using
35
44
Synchronous {+driver-short+}, consider the information in this section.
36
45
37
46
Synchronous {+driver-short+} is preferable if the following criteria applies to your
@@ -45,7 +54,7 @@ application or use case:
45
54
46
55
- You prefer the simplicity of synchronous logic when debugging your application
47
56
48
- Consider migrating to the {+driver-async+} driver if the following criteria applies
57
+ Consider migrating to the {+driver-async+} API if the following criteria applies
49
58
to your application or use case:
50
59
51
60
- Your application implements large, highly concurrent workloads (on the order of
@@ -56,19 +65,187 @@ to your application or use case:
56
65
57
66
- Your application relies on other asynchronous libraries or frameworks, such as FastAPI
58
67
68
+ Performance Benchmarks
69
+ ~~~~~~~~~~~~~~~~~~~~~~
70
+
71
+ The following table shows the performance benchmarks for different tasks
72
+ performed with the {+driver-async+} API and the Motor library. Each task was
73
+ performed with 10 iterations of 1000 documents each.
74
+
75
+ .. list-table::
76
+ :header-rows: 1
77
+ :widths: 20 40 40
78
+
79
+ * - Operation
80
+ - Motor Performance
81
+ - {+driver-async+} Performance
82
+
83
+ * - ``TestFindManyAndEmptyCursor``
84
+ - 74.074 MB/s
85
+ - 112.490 MB/s
86
+
87
+ * - ``TestFindManyAndEmptyCursor80Tasks``
88
+ - 37.181 MB/s
89
+ - 89.521 MB/s
90
+
91
+ * - ``TestFindManyAndEmptyCursor8Tasks``
92
+ - 63.145 MB/s
93
+ - 97.165 MB/s
94
+
95
+ * - ``TestFindOneByID``
96
+ - 3.121 MB/s
97
+ - 2.922 MB/s
98
+
99
+ * - ``TestFindOneByID80Tasks``
100
+ - 3.789 MB/s
101
+ - 4.071 MB/s
102
+
103
+ * - ``TestFindOneByID8Tasks``
104
+ - 3.697 MB/s
105
+ - 3.445 MB/s
106
+
107
+ * - ``TestFindOneByIDUnlimitedTasks``
108
+ - 3.866 MB/s
109
+ - 4.171 MB/s
110
+
111
+ * - ``TestGridFsDownload``
112
+ - 573.770 MB/s
113
+ - 603.578 MB/s
114
+
115
+ * - ``TestGridFsUpload``
116
+ - 430.870 MB/s
117
+ - 444.445 MB/s
118
+
119
+ * - ``TestLargeDocBulkInsert``
120
+ - 82.631 MB/s
121
+ - 102.105 MB/s
122
+
123
+ * - ``TestLargeDocClientBulkInsert``
124
+ - 75.057 MB/s
125
+ - 90.345 MB/s
126
+
127
+ * - ``TestLargeDocCollectionBulkInsert``
128
+ - 85.810 MB/s
129
+ - 101.838 MB/s
130
+
131
+ * - ``TestLargeDocInsertOne``
132
+ - 84.832 MB/s
133
+ - 101.934 MB/s
134
+
135
+ * - ``TestLargeDocInsertOneUnlimitedTasks``
136
+ - 120.389 MB/s
137
+ - 163.553 MB/s
138
+
139
+ * - ``TestRunCommand``
140
+ - 0.036 MB/s
141
+ - 0.034 MB/s
142
+
143
+ * - ``TestRunCommand80Tasks``
144
+ - 0.042 MB/s
145
+ - 0.043 MB/s
146
+
147
+ * - ``TestRunCommand8Tasks``
148
+ - 0.039 MB/s
149
+ - 0.041 MB/s
150
+
151
+ * - ``TestRunCommandUnlimitedTasks``
152
+ - 0.043 MB/s
153
+ - 0.042 MB/s
154
+
155
+ * - ``TestSmallDocBulkInsert``
156
+ - 35.071 MB/s
157
+ - 38.213 MB/s
158
+
159
+ * - ``TestSmallDocBulkMixedOps``
160
+ - 0.729 MB/s
161
+ - 0.446 MB/s
162
+
163
+ * - ``TestSmallDocClientBulkInsert``
164
+ - 25.032 MB/s
165
+ - 25.727 MB/s
166
+
167
+ * - ``TestSmallDocClientBulkMixedOps``
168
+ - 1.746 MB/s
169
+ - 1.723 MB/s
170
+
171
+ * - ``TestSmallDocCollectionBulkInsert``
172
+ - 34.144 MB/s
173
+ - 37.666 MB/s
174
+
175
+ * - ``TestSmallDocInsertOne``
176
+ - 0.539 MB/s
177
+ - 0.572 MB/s
178
+
179
+ * - ``TestSmallDocInsertOneUnlimitedTasks``
180
+ - 0.740 MB/s
181
+ - 0.786 MB/s
182
+
183
+ **Motor**
184
+
185
+ TestFindManyAndEmptyCursor 74.074 MB/s
186
+ TestFindManyAndEmptyCursor80Tasks 37.181 MB/s
187
+ TestFindManyAndEmptyCursor8Tasks 63.145 MB/s
188
+ TestFindOneByID 3.121 MB/s
189
+ TestFindOneByID80Tasks 3.789 MB/s
190
+ TestFindOneByID8Tasks 3.697 MB/s
191
+ TestFindOneByIDUnlimitedTasks 3.866 MB/s
192
+ TestGridFsDownload 573.770 MB/s
193
+ TestGridFsUpload 430.870 MB/s
194
+ TestLargeDocBulkInsert 82.631 MB/s
195
+ TestLargeDocClientBulkInsert 75.057 MB/s
196
+ TestLargeDocCollectionBulkInsert 85.810 MB/s
197
+ TestLargeDocInsertOne 84.832 MB/s
198
+ TestLargeDocInsertOneUnlimitedTasks 120.389 MB/s
199
+ TestRunCommand 0.036 MB/s
200
+ TestRunCommand80Tasks 0.042 MB/s
201
+ TestRunCommand8Tasks 0.039 MB/s
202
+ TestRunCommandUnlimitedTasks 0.043 MB/s
203
+ TestSmallDocBulkInsert 35.071 MB/s
204
+ TestSmallDocBulkMixedOps 0.729 MB/s
205
+ TestSmallDocClientBulkInsert 25.032 MB/s
206
+ TestSmallDocClientBulkMixedOps 1.746 MB/s
207
+ TestSmallDocCollectionBulkInsert 34.144 MB/s
208
+ TestSmallDocInsertOne 0.539 MB/s
209
+ TestSmallDocInsertOneUnlimitedTasks 0.740 MB/s
210
+
211
+ {+driver-async+}
212
+
213
+ TestFindManyAndEmptyCursor 112.490 MB/s
214
+ TestFindManyAndEmptyCursor8Tasks 97.165 MB/s
215
+ TestFindManyAndEmptyCursor80Tasks 89.521 MB/s
216
+ TestFindOneByID 2.922 MB/s
217
+ TestFindOneByID8Tasks 3.445 MB/s
218
+ TestFindOneByID80Tasks 4.071 MB/s
219
+ TestFindOneByIDUnlimitedTasks 4.171 MB/s
220
+ TestGridFsDownload 603.578 MB/s
221
+ TestGridFsUpload 444.445 MB/s
222
+ TestLargeDocBulkInsert 102.105 MB/s
223
+ TestLargeDocClientBulkInsert 90.345 MB/s
224
+ TestLargeDocCollectionBulkInsert 101.838 MB/s
225
+ TestLargeDocInsertOne 101.934 MB/s
226
+ TestLargeDocInsertOneUnlimitedTasks 163.553 MB/s
227
+ TestRunCommand 0.034 MB/s
228
+ TestRunCommand8Tasks 0.041 MB/s
229
+ TestRunCommand80Tasks 0.043 MB/s
230
+ TestRunCommandUnlimitedTasks 0.042 MB/s
231
+ TestSmallDocBulkInsert 38.213 MB/s
232
+ TestSmallDocBulkMixedOps 0.446 MB/s
233
+ TestSmallDocClientBulkInsert 25.727 MB/s
234
+ TestSmallDocClientBulkMixedOps 1.723 MB/s
235
+ TestSmallDocCollectionBulkInsert 37.666 MB/s
236
+ TestSmallDocInsertOne 0.572 MB/s
237
+ TestSmallDocInsertOneUnlimitedTasks 0.786 MB/s
238
+
59
239
Migrate From Motor
60
240
------------------
61
241
62
242
.. warning:: Motor Deprecation
63
-
64
- The {+driver-async+} driver is experimental. We do **not** recommend using it
65
- in production environments.
66
243
67
244
Motor will be deprecated one year after the **production release** of the
68
- {+driver-async+} driver . We strongly recommend that Motor users migrate to
69
- the {+driver-async+} driver while Motor is still supported.
245
+ {+driver-async+} API . We strongly recommend that Motor users migrate to
246
+ the {+driver-async+} API while Motor is still supported.
70
247
71
- The {+driver-async+} driver functions similarly to the Motor library, but allows
248
+ The {+driver-async+} API functions similarly to the Motor library, but allows
72
249
for improved latency and throughput due to directly using Python Asyncio instead
73
250
of delegating work to a thread pool. In most cases, you can directly migrate
74
251
existing Motor applications to {+driver-async+} by using ``AsyncMongoClient`` in
@@ -87,26 +264,26 @@ read and write operations in Motor compared to {+driver-async+}:
87
264
from pymongo import AsyncMongoClient
88
265
89
266
To see a list of the asynchronous methods available in the {+driver-async+}
90
- driver , see the :ref:`pymongo-async-methods` section. To learn about the versions of Motor
267
+ API , see the :ref:`pymongo-async-methods` section. To learn about the versions of Motor
91
268
that correspond to {+driver-short+}, see the :ref:`pymongo-motor-compatibility` section of
92
269
the Compatibility guide.
93
270
94
271
The following section shows the method signature changes that you must implement
95
- in your application when migrating from Motor to the {+driver-async+} driver .
272
+ in your application when migrating from Motor to the {+driver-async+} API .
96
273
97
274
.. warning::
98
275
99
- The {+driver-async+} driver does not support Tornado.
276
+ The {+driver-async+} API does not support Tornado.
100
277
101
278
Method Signature Changes
102
279
~~~~~~~~~~~~~~~~~~~~~~~~
103
280
104
- The following Motor method signatures behave differently in the {+driver-async+} driver :
281
+ The following Motor method signatures behave differently in the {+driver-async+} API :
105
282
106
283
- ``AsyncMongoClient.__init__()`` does not accept an ``io_loop`` parameter.
107
- - ``AsyncCursor.each()`` does not exist in the {+driver-async+} driver .
108
- - ``MotorGridOut.stream_to_handler()`` does not exist in the {+driver-async+} driver .
109
- - ``AsyncCursor.to_list(0)`` is not valid in the {+driver-async+} driver . Use
284
+ - ``AsyncCursor.each()`` does not exist in the {+driver-async+} api-root .
285
+ - ``MotorGridOut.stream_to_handler()`` does not exist in the {+driver-async+} API .
286
+ - ``AsyncCursor.to_list(0)`` is not valid in the {+driver-async+} API . Use
110
287
``to_list(None)`` instead.
111
288
- ``MongoClient`` is thread safe and can be used by many threads, however, an
112
289
``AsyncMongoClient`` is not thread safe and should only be used by a single
@@ -115,13 +292,13 @@ The following Motor method signatures behave differently in the {+driver-async+}
115
292
.. warning::
116
293
117
294
Motor users may experience a degradation of performance when switching to the
118
- {+driver-async+} driver . This is due to the {+driver-async+} driver using native
295
+ {+driver-async+} API . This is due to the {+driver-async+} API using native
119
296
``asyncio`` tasks instead of thread-based executors. Thread-based executors
120
297
have similar performance characteristics to the synchronous driver, but slower.
121
298
This means they perform better for workloads that do not fit the preceding criteria
122
- for the {+driver-async+} driver .
299
+ for the {+driver-async+} API .
123
300
124
- If you are experiencing performance slowdown, identify whether the {+driver-async+} driver
301
+ If you are experiencing performance slowdown, identify whether the {+driver-async+} API
125
302
is necessary for your usecase. If you determine your use case is better served by
126
303
synchronous {+driver-short+}, consider using the synchronous driver
127
304
with ``asyncio.loop.run_in_executor()`` for asynchronous compatibility. To learn more, see
@@ -132,7 +309,7 @@ The following Motor method signatures behave differently in the {+driver-async+}
132
309
Migrate from {+driver-short+}
133
310
-----------------------------
134
311
135
- The {+driver-async+} driver behaves similarly to {+driver-short+}, but
312
+ The {+driver-async+} API behaves similarly to {+driver-short+}, but
136
313
all methods that perform network operations are coroutines and must be awaited.
137
314
To migrate from {+driver-short+} to {+driver-async+}, you must update your code
138
315
in the following ways:
@@ -142,11 +319,11 @@ in the following ways:
142
319
- If you call an asynchronous method inside a function, mark the function as ``async``.
143
320
144
321
Keep the following points in mind when migrating from synchronous {+driver-short+}
145
- to the {+driver-async+} driver :
322
+ to the {+driver-async+} API :
146
323
147
324
- To convert an ``AsyncCursor`` to a list, you must use the asynchronous ``cursor.to_list()``
148
325
method.
149
- - The ``AsyncCollection.find()`` method in the {+driver-async+} driver is synchronous, but
326
+ - The ``AsyncCollection.find()`` method in the {+driver-async+} API is synchronous, but
150
327
returns an ``AsyncCursor``. To iterate through the cursor, you must use an ``async for``
151
328
loop.
152
329
- The ``AsyncMongoClient`` object does not support the ``connect`` keyword argument.
@@ -163,7 +340,7 @@ to the {+driver-async+} driver:
163
340
Asynchronous Methods
164
341
--------------------
165
342
166
- For a complete list of asynchronous methods available in the {+driver-async+} driver ,
343
+ For a complete list of asynchronous methods available in the {+driver-async+} API ,
167
344
see the `API documentation <{+api-root+}pymongo/asynchronous/index.html>`__.
168
345
169
346
.. note::
0 commit comments