NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #1308 most downloaded on PyPI
Non-blocking MongoDB driver for Tornado or asyncio
Last release 1 years ago
14 May 2025
Ships fairly regularly
a new release about every 3 months
Most releases are documented
notes for 39 of 51 stable releases
Nothing withdrawn
no release was ever pulled
14 years old
57 releases · first in 2013
Community notes: https://www.mongodb.com/community/forums/t/motor-3-7-1-released/321388 .
Community notes: https://www.mongodb.com/community/forums/t/motor-3-7-1-released/321388.
The 3.7.1 release contains only documentation changes.
Warning
As of May 14th, 2025, Motor is deprecated in favor of the GA release of the PyMongo Async API. No new features will be added to Motor, and only bug fixes will be provided until it reaches end of life on May 14th, 2026. After that, only critical bug fixes will be made until final support ends on May 14th, 2027. We strongly recommend migrating to the PyMongo Async API while Motor is still supported. For help transitioning, see the Migrate to PyMongo Async guide.
The 3.7.1 release contains only documentation changes.
Warning
Motor will be deprecated on May 14th, 2026, one year after the production release of the PyMongo Async driver. Critical bug fixes will be made until May 14th, 2027. We strongly recommend that Motor users migrate to the PyMongo Async driver while Motor is still supported. To learn more, see the migration guide.
One column per quarter.
Community notes: https://www.mongodb.com/community/forums/t/motor-3-7-0-released/311077/3
Add support for PyMongo 4.10.
Drop support for Python 3.8.
Drop support for MongoDB 3.6.
PYTHON-4962 Adopt zizmor GitHub Actions security scanner by @blink1073 in #312
Full Changelog: 3.6.0...3.6.1
Add return type to to_list method in stub file.
Fix ability to install pymongo from source while testing.
Community notes: https://www.mongodb.com/community/forums/t/motor-3-6-0-released/297834
Add support for MongoDB 8.0 and PyMongo 4.9.
The length parameter in MotorCursor.to_list is now optional.
Note
This is the last planned minor version of Motor. We are sunsetting Motor in favor of native asyncio support in PyMongo 4.9+. We will continue to provide security releases and bug fixes for Motor, but it will not gain new features.
Add GitHub Attestation support to release process.
Add GitHub Attestation support to release process.
Update the PyMongo dependency requirement to >=4.5 and <4.9. Apps that require PyMongo >=4.9 must upgrade to Motor >=3.6.
Update the PyMongo dependency requirement to >=4.5 and <4.9. Apps that require PyMongo >=4.9 must upgrade to Motor >=3.6.
MOTOR-1335 AsyncIOMotorClient is not suscriptable by @blink1073 in #293
Full Changelog: 3.5.0...3.5.1
Fix runtime behavior of Motor generic class typing, e.g. client: AsyncIOMotorClient[Dict[str, Any]].
Switch to using Hatchling as a build backend and remove setup.py.
Full Changelog: 3.4.0...3.5.0
Nothing published for this version
Nothing published for this version
Type hint bug fixes and improvements. Added typings to classes in motor_tornado and motor_asyncio.
Type hint bug fixes and improvements. Added typings to classes in motor_tornado and motor_asyncio.
Fix incorrect type hints for the following: MotorCursor.to_list, MotorCollection.name, MotorDatabase.get_collection, MotorClientSession.with_transacti
Fix incorrect type hints for the following: MotorCursor.to_list, MotorCollection.name, MotorDatabase.get_collection, MotorClientSession.with_transaction
Fix a bug that caused application-supplied DriverInfo to be overwritten.
Fix a bug in the type hint for MotorCursor.to_list.
Fix a bug in the type hint for MotorCursor.to_list.
Add inline type hints for public APIs.
Add support for PyMongo 4.4+.
Add support for Python 3.12.
Add inline type hints for public APIs.
Added new helper methods for Atlas Search Index (requires MongoDB Server 7.0+): ~motor.motor_tornado.MotorCollection.list_search_indexes, ~motor.motor_tornado.MotorCollection.create_search_index, ~motor.motor_tornado.MotorCollection.create_search_indexes, ~motor.motor_tornado.MotorCollection.drop_search_index, ~motor.motor_tornado.MotorCollection.update_search_index
Added ~motor.motor_tornado.MotorDatabase.cursor_command and ~motor.motor_tornado.MotorCommandCursor.try_next to support executing an arbitrary command that returns a cursor.
…Backwards-breaking changes may be made before the final release.
Add support for MongoDB 7.0 and PyMongo 4.4+.
Add support for Queryable Encryption helpers ~motor.core.MotorClientEncryption.create_encrypted_collection and ~motor.core.MotorClientEncryption.encrypt_expression. Backwards-breaking changes may be made before the final release.
pymongocrypt 1.6.0 or later is now required for Client Side Field Level Encryption (CSFLE) and Queryable Encryption (QE) support. MongoDB Server 7.0 introduced a backwards breaking change to the QE protocol. Users taking advantage of the QE must now upgrade to MongoDB 7.0+ and Motor 3.2+.
Nothing published for this version
Motor 3.1.1 adds support for Python 3.11 and fixes a bug that caused an ImportError in Python 3.11.0.
Motor 3.1.1 adds support for Python 3.11 and fixes a bug that caused an ImportError in Python 3.11.0.
Nothing published for this version
Nothing published for this version
Motor 2.5.1 fixes a bug where MotorCursor.to_list could return more than length documents.
Motor 2.5.1 fixes a bug where MotorCursor.to_list could return more than length documents.
See the Motor 2.5.1 release notes in JIRA for the complete list of resolved issues in this release.
Nothing published for this version
Nothing published for this version
Motor 2.3.1 fixes two bugs related to change streams.
Motor 2.3.1 fixes two bugs related to change streams.
Bug-fixes:
The motor.motor_asyncio.AsyncIOMotorCollection.watch() , motor.motor_asyncio.AsyncIOMotorDatabase.watch() , and motor.motor_asyncio.AsyncIOMotorClient.watch() methods now properly support passing AsyncIOMotorClientSession via the session argument.
Avoid exhausting Motor’s worker thread pool when many change streams are being iterated simultaneously.
See the Motor 2.3.1 release notes in JIRA for the complete list of resolved issues in this release.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Fix a Python 3.7 compatibility bug caused by importing “async”, which is a keyword in Python 3.7. Drop support for Python 3.4.3 and older.
Fix a Python 3.7 compatibility bug caused by importing “async”, which is a keyword in Python 3.7. Drop support for Python 3.4.3 and older.
Deprecate Motor’s old callback-based async API in preparation for removing it in Motor 2.0. Raise DeprecationWarning whenever a callback is passed.
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 Motor 2.0 Migration Guide .
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 migrate-to-motor-2.
Fix a Python 3.7 compatibility bug caused by importing “async”, which is a keyword in Python 3.7. Drop support for Python 3.4.3 and older.
Fix a Python 3.7 compatibility bug caused by importing “async”, which is a keyword in Python 3.7. Drop support for Python 3.4.3 and older.
Fix a Python 3.7 compatibility bug in the MotorChangeStream class returned by MotorCollection.watch() . It is now possible to use change streams in as
Fix a Python 3.7 compatibility bug in the MotorChangeStream class returned by MotorCollection.watch() . It is now possible to use change streams in async for loops in Python 3.7.
Motor 1.2.0 requires PyMongo 3.6 or later. The dependency was properly documented, but not enforced in setup.py . PyMongo 3.6 is now an install-time r
Motor 1.2.0 requires PyMongo 3.6 or later. The dependency was properly documented, but not enforced in setup.py . PyMongo 3.6 is now an install-time requirement; thanks to Shane Harvey for the fix.
An asyncio application that created a Change Stream with MotorCollection.watch() and shut down while the Change Stream was open would print several er
An asyncio application that created a Change Stream with MotorCollection.watch() and shut down while the Change Stream was open would print several errors. I have rewritten MotorChangeStream.next() and some Motor internals to allow clean shutdown with asyncio.
Nothing published for this version
Nothing published for this version
Motor depends on PyMongo 3.4 or later. It wraps the latest PyMongo code which support the new server features introduced in MongoDB 3.4. (It is a coin
Motor depends on PyMongo 3.4 or later. It wraps the latest PyMongo code which support the new server features introduced in MongoDB 3.4. (It is a coincidence that the latest MongoDB and PyMongo versions are the same number.)
Highlights include:
Complete support for MongoDB 3.4:
Unicode aware string comparison using collations. See PyMongo’s examples for collation .
MotorCursor and MotorGridOutCursor have a new attribute collation() .
Support for the new Decimal128 BSON type.
A new maxStalenessSeconds read preference option.
A username is no longer required for the MONGODB-X509 authentication mechanism when connected to MongoDB >= 3.4.
parallel_scan() supports maxTimeMS.
WriteConcern is automatically applied by all helpers for commands that write to the database when connected to MongoDB 3.4+. This change affects the following helpers:
MotorClient.drop_database()
MotorDatabase.create_collection()
MotorDatabase.drop_collection()
MotorCollection.aggregate() (when using $out)
MotorCollection.create_indexes()
MotorCollection.create_index()
MotorCollection.drop_indexes()
MotorCollection.drop_indexes()
MotorCollection.drop_index()
MotorCollection.map_reduce() (when output is not “inline”)
MotorCollection.reindex()
MotorCollection.rename()
Improved support for logging server discovery and monitoring events. See PyMongo's monitoring documentation for examples.
Support for matching iPAddress subjectAltName values for TLS certificate verification.
TLS compression is now explicitly disabled when possible.
The Server Name Indication (SNI) TLS extension is used when possible.
PyMongo’s bson module provides finer control over JSON encoding/decoding with JSONOptions .
Allow Code objects to have a scope of None , signifying no scope. Also allow encoding Code objects with an empty scope (i.e. {} ).
Warning
Starting in PyMongo 3.4, bson.code.Code.scope may return None , as the default scope is None instead of {} .
Note
PyMongo 3.4+ attempts to create sockets non-inheritable when possible (i.e. it sets the close-on-exec flag on socket file descriptors). Support is limited to a subset of POSIX operating systems (not including Windows) and the flag usually cannot be set in a single atomic operation. CPython 3.4+ implements PEP 446 , creating all file descriptors non-inheritable by default. Users that require this behavior are encouraged to upgrade to CPython 3.4+.
These classes supersede the old MotorGridFS and AsyncIOMotorGridFS . See GridFS changes below, especially note the breaking change in GridFSHandler .
Motor now depends on PyMongo 3.3 and later. The move from PyMongo 2 to 3 brings a large number of API changes, read the the PyMongo 3 changelog carefully.
In Motor 1.0, MotorClient is the only class. Connect to a replica set with a “replicaSet” URI option or parameter:
MotorClient ( "mongodb://hostname/?replicaSet=my-rs" ) MotorClient ( host , port , replicaSet = "my-rs" )
New classes MotorGridFSBucket and AsyncIOMotorGridFSBucket conform to the GridFS API Spec for MongoDB drivers. These classes supersede the old MotorGridFS and AsyncIOMotorGridFS . See GridFS changes below, especially note the breaking change in GridFSHandler .
Serve GridFS files over HTTP using aiohttp and AIOHTTPGridFS .
Removed:
MotorClient.open() ; clients have opened themselves automatically on demand since version 0.2.
MotorClient.seeds , use pymongo.uri_parser.parse_uri() on your MongoDB URI.
MotorClient.alive
Added:
MotorClient.event_listeners
MotorClient.max_idle_time_ms
MotorClient.min_pool_size
Unix domain socket paths must be quoted with urllib.parse.quote_plus() (or urllib.quote_plus in Python 2) before they are included in a URI:
path = '/tmp/mongodb-27017.sock' MotorClient ( 'mongodb:// %s ' % urllib . parse . quote_plus ( path ))
Added:
MotorCollection.create_indexes()
MotorCollection.list_indexes()
New bypass_document_validation parameter for initialize_ordered_bulk_op() and initialize_unordered_bulk_op() .
The following find/find_one options have been renamed:
These renames only affect your code if you passed these as keyword arguments, like find(fields=['fieldname']) . If you passed only positional parameters these changes are not significant for your application.
spec -> filter
fields -> projection
partial -> allow_partial_results
The following find/find_one options have been added:
cursor_type (see CursorType for values)
oplog_replay
modifiers
The following find/find_one options have been removed:
network_timeout (use max_time_ms() instead)
read_preference (use with_options() instead)
tag_sets (use one of the read preference classes from read_preferences and with_options() instead)
secondary_acceptable_latency_ms (use the localThresholdMS URI option instead)
max_scan (use the new modifiers option instead)
snapshot (use the new modifiers option instead)
tailable (use the new cursor_type option instead)
await_data (use the new cursor_type option instead)
exhaust (use the new cursor_type option instead)
as_class (use with_options() with CodecOptions instead)
compile_re (BSON regular expressions are always decoded to Regex )
The following find/find_one options are deprecated:
The following renames need special handling.
Added:
MotorCursor.address
MotorCursor.max_await_time_ms()
Removed:
The old GridFS classes MotorGridFS and AsyncIOMotorGridFS are deprecated in favor of MotorGridFSBucket and AsyncIOMotorGridFSBucket , which comply with MongoDB’s cross-language driver spec for GridFS.
The old classes are still supported, but will be removed in Motor 2.0.
BREAKING CHANGE : The overridable method get_gridfs_file of GridFSHandler now takes a MotorGridFSBucket , not a MotorGridFS . It also takes an additional request parameter.
Added:
MotorGridOutCursor.address
MotorGridOutCursor.max_await_time_ms()
Removed:
New method MotorGridIn.abort() .
In a Python 3.5 native coroutine, the “async with” statement calls close() automatically:
async def upload (): my_db = MotorClient () . test fs = MotorGridFSBucket ( my_db ) async with await fs . open_upload_stream ( "test_file" , metadata = { "contentType" : "text/plain" }) as gridin : await gridin . write ( b 'First part \n ' ) await gridin . write ( b 'Second part' ) # gridin is now closed automatically.
MotorGridOut is now an async iterable, so reading a chunk at a time is much simpler with a Python 3 native coroutine:
async def read_file ( file_id ): fs = motor . motor_tornado . MotorGridFS ( db ) gridout = await fs . get ( file_id ) async for chunk in gridout : sys . stdout . write ( chunk ) sys . stdout . flush ()
The Motor asyncio API is now fully documented, side by side with the Motor Tornado API .
New Developer Guide added.
Motor now depends on PyMongo 3.3 and later. The move from PyMongo 2 to 3 brings a large number of API changes, read the the PyMongo 3 changelog carefully.
In Motor 1.0, MotorClient is the only class. Connect to a replica set with a "replicaSet" URI option or parameter:
MotorClient("mongodb://hostname/?replicaSet=my-rs")
MotorClient(host, port, replicaSet="my-rs")
New classes ~motor.motor_tornado.MotorGridFSBucket and ~motor.motor_asyncio.AsyncIOMotorGridFSBucket conform to the GridFS API Spec for MongoDB drivers. These classes supersede the old MotorGridFS and AsyncIOMotorGridFS. See GridFS changes below, especially note the breaking change in ~motor.motor_web.GridFSHandler.
Serve GridFS files over HTTP using aiohttp and ~motor.aiohttp.AIOHTTPGridFS.
Removed:
MotorClient.open; clients have opened themselves automatically on demand since version 0.2.
MotorClient.seeds, use pymongo.uri_parser.parse_uri on your MongoDB URI.
MotorClient.alive
Added:
MotorClient.event_listeners
MotorClient.max_idle_time_ms
MotorClient.min_pool_size
Unix domain socket paths must be quoted with urllib.parse.quote_plus (or urllib.quote_plus in Python 2) before they are included in a URI:
path = "/tmp/mongodb-27017.sock"
MotorClient("mongodb://%s" % urllib.parse.quote_plus(path))
Added:
MotorCollection.create_indexes
MotorCollection.list_indexes
New bypass_document_validation parameter for ~.MotorCollection.initialize_ordered_bulk_op and ~.MotorCollection.initialize_unordered_bulk_op.
The following find/find_one options have been renamed:
These renames only affect your code if you passed these as keyword arguments, like find(fields=['fieldname']). If you passed only positional parameters these changes are not significant for your application.
spec -> filter
fields -> projection
partial -> allow_partial_results
The following find/find_one options have been added:
cursor_type (see ~pymongo.cursor.CursorType for values)
oplog_replay
modifiers
The following find/find_one options have been removed:
network_timeout (use ~motor.motor_tornado.MotorCursor.max_time_ms instead)
read_preference (use ~motor.motor_tornado.MotorCollection.with_options instead)
tag_sets (use one of the read preference classes from ~pymongo.read_preferences and ~motor.motor_tornado.MotorCollection.with_options instead)
secondary_acceptable_latency_ms (use the localThresholdMS URI option instead)
max_scan (use the new modifiers option instead)
snapshot (use the new modifiers option instead)
tailable (use the new cursor_type option instead)
await_data (use the new cursor_type option instead)
exhaust (use the new cursor_type option instead)
as_class (use ~motor.motor_tornado.MotorCollection.with_options with ~pymongo.codec_options.CodecOptions instead)
compile_re (BSON regular expressions are always decoded to ~pymongo.regex.Regex)
The following find/find_one options are deprecated:
manipulate
The following renames need special handling.
timeout -> no_cursor_timeout - By default, MongoDB closes a cursor after 10 minutes of inactivity. In previous Motor versions, you disabled the timeout by passing timeout=False to .MotorCollection.find or .MotorGridFS.find. The timeout parameter has been renamed to no_cursor_timeout, it defaults to False, and you must now pass no_cursor_timeout=True to disable timeouts.
Added:
.MotorCursor.address
.MotorCursor.max_await_time_ms
Removed:
.MotorCursor.conn_id, use ~.MotorCursor.address
The old GridFS classes MotorGridFS and AsyncIOMotorGridFS are deprecated in favor of ~motor.motor_tornado.MotorGridFSBucket and ~motor.motor_asyncio.AsyncIOMotorGridFSBucket, which comply with MongoDB's cross-language driver spec for GridFS.
The old classes are still supported, but will be removed in Motor 2.0.
BREAKING CHANGE: The overridable method ~motor.web.GridFSHandler.get_gridfs_file of ~motor.web.GridFSHandler now takes a ~motor.motor_tornado.MotorGridFSBucket, not a ~motor.motor_tornado.MotorGridFS. It also takes an additional request parameter.
Added:
.MotorGridOutCursor.address
.MotorGridOutCursor.max_await_time_ms
Removed:
.MotorGridOutCursor.conn_id, use ~.MotorGridOutCursor.address
New method .MotorGridIn.abort.
In a Python 3.5 native coroutine, the "async with" statement calls ~MotorGridIn.close automatically:
async def upload():
my_db = MotorClient().test
fs = MotorGridFSBucket(my_db)
async with await fs.open_upload_stream(
"test_file", metadata={"contentType": "text/plain"}) as gridin:
await gridin.write(b'First part\n')
await gridin.write(b'Second part')
# gridin is now closed automatically.
~motor.motor_tornado.MotorGridOut is now an async iterable, so reading a chunk at a time is much simpler with a Python 3 native coroutine:
async def read_file(file_id):
fs = motor.motor_tornado.MotorGridFS(db)
gridout = await fs.get(file_id)
async for chunk in gridout:
sys.stdout.write(chunk)
sys.stdout.flush()
The /api-asyncio/index is now fully documented, side by side with the /api-tornado/index.
New developer-guide added.
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.
For asynchronous I/O Motor now uses a thread pool, which is faster and simpler than the prior implementation with greenlets. It no longer requires the greenlet package, and now requires the futures backport package on Python 2.
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.
The get_database method is added for getting a MotorDatabase instance with its options configured differently than the MotorClient’s.
New read-only attributes:
codec_options
local_threshold_ms
max_write_batch_size
The get_database() method is added for getting a MotorDatabase instance with its options configured differently than the MotorReplicaSetClient’s.
New read-only attributes:
codec_options
local_threshold_ms
The get_collection() method is added for getting a MotorCollection instance with its options configured differently than the MotorDatabase’s.
The connection property is deprecated in favor of a new read-only attribute client .
New read-only attribute:
The with_options() method is added for getting a MotorCollection instance with its options configured differently than this MotorCollection’s.
New read-only attribute:
The following methods wrap PyMongo’s implementation of the standard CRUD API Spec for MongoDB Drivers:
bulk_write()
insert_one()
insert_many()
update_one()
update_many()
replace_one()
delete_one()
delete_many()
find_one_and_delete()
find_one_and_replace()
find_one_and_update()
These new methods do not apply SON Manipulators.
New MotorGridOutCursor methods:
add_option()
remove_option()
clone()
Added MotorGridOut documentation:
aliases
chunk_size
close()
content_type
filename
length
md5
metadata
name
upload_date
MOTOR-124 : an import deadlock in Python 2 and Tornado 3 led to an AutoReconnect exception with some replica sets.
For asynchronous I/O Motor now uses a thread pool, which is faster and simpler than the prior implementation with greenlets. It no longer requires the greenlet package, and now requires the futures backport package on Python 2.
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.
The ~MotorClient.get_database method is added for getting a MotorDatabase instance with its options configured differently than the MotorClient's.
New read-only attributes:
~MotorClient.codec_options
~MotorClient.local_threshold_ms
~MotorClient.max_write_batch_size
The ~MotorReplicaSetClient.get_database method is added for getting a MotorDatabase instance with its options configured differently than the MotorReplicaSetClient's.
New read-only attributes:
~MotorReplicaSetClient.codec_options
~MotorReplicaSetClient.local_threshold_ms
The ~MotorDatabase.get_collection method is added for getting a MotorCollection instance with its options configured differently than the MotorDatabase's.
The connection property is deprecated in favor of a new read-only attribute ~MotorDatabase.client.
New read-only attribute:
~MotorDatabase.codec_options
The ~MotorCollection.with_options method is added for getting a MotorCollection instance with its options configured differently than this MotorCollection's.
New read-only attribute:
~MotorCollection.codec_options
The following methods wrap PyMongo's implementation of the standard CRUD API Spec for MongoDB Drivers:
~MotorCollection.bulk_write
~MotorCollection.insert_one
~MotorCollection.insert_many
~MotorCollection.update_one
~MotorCollection.update_many
~MotorCollection.replace_one
~MotorCollection.delete_one
~MotorCollection.delete_many
~MotorCollection.find_one_and_delete
~MotorCollection.find_one_and_replace
~MotorCollection.find_one_and_update
These new methods do not apply SON Manipulators.
New MotorGridOutCursor methods:
~MotorGridOutCursor.add_option
~MotorGridOutCursor.remove_option
~MotorGridOutCursor.clone
Added MotorGridOut documentation:
~MotorGridOut.aliases
~MotorGridOut.chunk_size
~MotorGridOut.close
~MotorGridOut.content_type
~MotorGridOut.filename
~MotorGridOut.length
~MotorGridOut.md5
~MotorGridOut.metadata
~MotorGridOut.name
~MotorGridOut.upload_date
MOTOR-124: an import deadlock in Python 2 and Tornado 3 led to an ~pymongo.errors.AutoReconnect exception with some replica sets.
Nothing published for this version
Fix “from motor import *” for Python 3.
Fix “from motor import *” for Python 3.
Fix source distribution, which hadn’t included the “frameworks” submodules.
Fix source distribution, which hadn’t included the “frameworks” submodules.
This is a bugfix release. Fixing these bugs has introduced tiny API changes that may affect some programs.
This is a bugfix release. Fixing these bugs has introduced tiny API changes that may affect some programs.
These modules have been moved from:
motor_asyncio.py
motor_tornado.py
To:
motor_asyncio/init.py
motor_tornado/init.py
Motor had to make this change in order to omit the motor_asyncio submodule entirely and avoid a spurious SyntaxError being printed when installing in Python 2. The change should be invisible to application code.
A database or collection whose name starts with an underscore can no longer be accessed as a property:
Such databases and collections can still be accessed dict-style:
To ensure a “sub-collection” with a name that includes an underscore is accessible, Motor collections now allow dict-style access, the same as Motor clients and databases always have:
These changes solve problems with iPython code completion and the Python 3 ABC abstract base class.
Motor 0.5 deprecates a large number of APIs that will be removed in version 1.0:
Motor can now integrate with asyncio, as an alternative to Tornado. My gratitude to Rémi Jolin, Andrew Svetlov, and Nikolay Novik for their huge contributions to Motor’s asyncio integration.
Motor is now compatible with Python 3.5, which required some effort. Motor not only supports users’ coroutines, it uses coroutines to implement some of its own features, like open() and put() . There is no single way to return a value from a Python 3.5 native coroutine or a Python 2 generator-based coroutine, so Motor internal coroutines that return values were rewritten. (See commit message dc19418c for an explanation.)
Motor now supports Python 3.5 native coroutines, written with the async and await syntax:
async def f (): await collection . insert ({ '_id' : 1 })
Cursors from find() , aggregate() , or find() can be iterated elegantly and very efficiently in native coroutines with async for :
async def f (): async for doc in collection . find (): do_something_with ( doc )
MotorCollection.aggregate() now returns a cursor by default, and the cursor is returned immediately without a yield . The old syntax is no longer supported:
In Motor 0.5, simply do:
Or with Python 3.5 and later:
MongoDB versions 2.4 and older do not support aggregation cursors. For compatibility with older MongoDBs, aggregate() now takes an argument cursor=False , and returns a Future that you can yield to get all the results in one document:
Motor 0.5 deprecates a large number of APIs that will be removed in version 1.0:
MotorClient :
~MotorClient.host
~MotorClient.port
~MotorClient.document_class
~MotorClient.tz_aware
~MotorClient.secondary_acceptable_latency_ms
~MotorClient.tag_sets
~MotorClient.uuid_subtype
~MotorClient.disconnect
~MotorClient.alive MotorReplicaSetClient :
~MotorReplicaSetClient.document_class
~MotorReplicaSetClient.tz_aware
~MotorReplicaSetClient.secondary_acceptable_latency_ms
~MotorReplicaSetClient.tag_sets
~MotorReplicaSetClient.uuid_subtype
~MotorReplicaSetClient.alive MotorDatabase :
~MotorDatabase.secondary_acceptable_latency_ms
~MotorDatabase.tag_sets
~MotorDatabase.uuid_subtype MotorCollection :
~MotorCollection.secondary_acceptable_latency_ms
~MotorCollection.tag_sets
~MotorCollection.uuid_subtype
Cursors can no longer be indexed like cursor[n] or sliced like cursor[start:end] , see MOTOR-84 . If you wrote code like this:
cursor = collection . find ()[ i ] yield cursor . fetch_next doc = cursor . next_object ()
Then instead, write:
cursor = collection . find () . skip ( i ) . limit ( - 1 ) yield cursor . fetch_next doc = cursor . next_object ()
The negative limit ensures the server closes the cursor after one result, saving Motor the work of closing it. See cursor.limit .
When you use Motor with Tornado and SSL hostname validation fails, Motor used to raise a ConnectionFailure with a useful messsage like “hostname ‘X’ doesn’t match ‘Y’”. The message is now empty and Tornado logs a warning instead.
You can now get and set uuid_subtype on MotorClient , MotorReplicaSetClient , and MotorDatabase instances, not just on MotorCollection .
Nothing published for this version
Fix MOTOR-66 , deadlock when initiating MotorReplicaSetClient connection from multiple operations at once.
Fix MOTOR-66 , deadlock when initiating MotorReplicaSetClient connection from multiple operations at once.
Supports MongoDB 3.0. In particular, supports MongoDB 3.0’s new SCRAM-SHA-1 authentication mechanism and updates the implementations of MotorClient.da
Supports MongoDB 3.0. In particular, supports MongoDB 3.0’s new SCRAM-SHA-1 authentication mechanism and updates the implementations of MotorClient.database_names() and MotorDatabase.collection_names() .
Updates PyMongo dependency from 2.7.1 to 2.8, therefore inheriting PyMongo 2.7.2’s bug fixes and PyMongo 2.8’s bug fixes and features .
Fixes a connection-pool timeout when waitQueueMultipleMS is set and two bugs in replica set monitoring .
The copy_database method has been removed. It was overly complex and no one used it, see MOTOR-56 . You can still use the MotorDatabase.command() method directly. The only scenario not supported is copying a database from one host to another, if the remote host requires authentication. For this, use PyMongo’s copy_database method, or, since PyMongo’s copy_database will be removed in a future release too, use the mongo shell.
See also
The “copydb” command .
Nothing published for this version
Fix MOTOR-45 , a stack-context leak in domain name resolution that could lead to an infinite loop and rapid memory leak.
Fix MOTOR-45 , a stack-context leak in domain name resolution that could lead to an infinite loop and rapid memory leak.
Document Motor’s Requirements in detail.
Fix MOTOR-44 , a socket leak in MotorClient.copy_database and MotorReplicaSetClient.copy_database .
Fix MOTOR-44 , a socket leak in MotorClient.copy_database and MotorReplicaSetClient.copy_database .
Fix MOTOR-43 , a TypeError when using GridFSHandler with a timezone-aware MotorClient .
Fix MOTOR-43 , a TypeError when using GridFSHandler with a timezone-aware MotorClient .
Fix GridFS examples that hadn’t been updated for Motor 0.2’s new syntax.
Fix a unittest that hadn’t been running.
Fix MOTOR-43, a TypeError when using ~motor.web.GridFSHandler with a timezone-aware ~motor.motor_tornado.MotorClient.
Fix GridFS examples that hadn't been updated for Motor 0.2's new syntax.
Fix a unittest that hadn't been running.
Updates PyMongo dependency from 2.7 to 2.7.1, therefore inheriting PyMongo 2.7.1’s bug fixes .
No new features.
Updates PyMongo dependency from 2.7 to 2.7.1, therefore inheriting PyMongo 2.7.1’s bug fixes .
Motor continues to support Python 2.6, 2.7, 3.3, and 3.4, but now with single-source. 2to3 no longer runs during installation with Python 3.
nosetests is no longer required for regular Motor tests.
Fixes a mistake in the docstring for aggregate().
MOTOR-32 : The documentation for MotorCursor.close() claimed it immediately halted execution of MotorCursor.each() , but it didn’t.
Fixes two bugs:
MOTOR-32 : The documentation for MotorCursor.close() claimed it immediately halted execution of MotorCursor.each() , but it didn’t.
MOTOR-33 : An incompletely iterated cursor’s del method sometimes got stuck and cost 100% CPU forever, even though the application was still responsive.
motor.Op works the same as before, but it’s deprecated.
This version includes API changes that break backward compatibility with applications written for Motor 0.1. For most applications, the migration chores will be minor. In exchange, Motor 0.2 offers a cleaner style, and it wraps the new and improved PyMongo 2.7 instead of 2.5.
Motor now requires PyMongo 2.7.0 exactly and Tornado 3 or later. It drops support for Python 2.5 since Tornado 3 has dropped it.
Motor continues to work with Python 2.6 through 3.4. It still requires Greenlet .
The open_sync method has been removed from MotorClient and MotorReplicaSetClient . Clients now connect to MongoDB automatically on first use. Simply delete the call to open_sync from your application.
If it’s important to test that MongoDB is available before continuing your application’s startup, use IOLoop.run_sync :
loop = tornado . ioloop . IOLoop . current () client = motor . MotorClient ( host , port ) try : loop . run_sync ( client . open ) except pymongo . errors . ConnectionFailure : print "Can't connect"
Similarly, calling MotorGridOut.open() is now optional. MotorGridIn and MotorGridFS no longer have an open method at all.
Motor 0.2 takes advantage of Tornado’s tidy new coroutine syntax:
To make this possible, Motor asynchronous methods (except MotorCursor.each() ) now return a Future .
Using Motor with callbacks is still possible: If a callback is passed, it will be executed with the (result, error) of the operation, same as in Motor 0.1:
def callback ( document , error ): if error : logging . error ( "Oh no!" ) else : print document collection . find_one ({ '_id' : my_id }, callback = callback )
If no callback is passed, a Future is returned that resolves to the method’s result or error:
document = yield collection . find_one ({ '_id' : my_id })
motor.Op works the same as before, but it’s deprecated.
WaitOp and WaitAllOps have been removed. Code that used them can now yield a Future or a list of them. Consider this function written for Tornado 2 and Motor 0.1:
@gen . engine def get_some_documents (): cursor = collection . find () . sort ( '_id' ) . limit ( 2 ) cursor . to_list ( callback = ( yield gen . Callback ( 'key' ))) do_something_while_we_wait () try : documents = yield motor . WaitOp ( 'key' ) print documents except Exception , e : print e
The function now becomes:
@gen . coroutine def f (): cursor = collection . find () . sort ( '_id' ) . limit ( 2 ) future = cursor . to_list ( 2 ) do_something_while_we_wait () try : documents = yield future print documents except Exception , e : print e
Similarly, a function written like so in the old style:
@gen . engine def get_two_documents_in_parallel ( collection ): collection . find_one ( { '_id' : 1 }, callback = ( yield gen . Callback ( 'one' ))) collection . find_one ( { '_id' : 2 }, callback = ( yield gen . Callback ( 'two' ))) try : doc_one , doc_two = yield motor . WaitAllOps ([ 'one' , 'two' ]) print doc_one , doc_two except Exception , e : print e
Now becomes:
@gen . coroutine def get_two_documents_in_parallel ( collection ): future_0 = collection . find_one ({ '_id' : 1 }) future_1 = collection . find_one ({ '_id' : 2 }) try : doc_one , doc_two = yield [ future_0 , future_1 ] print doc_one , doc_two except Exception , e : print e
Any calls to MotorCursor.to_list() that omitted the length argument must now include it:
result = yield collection . find () . to_list ( 100 )
None is acceptable, meaning “unlimited.” Use with caution.
MotorPool has been rewritten. It supports the new options introduced in PyMongo 2.6, and drops all Motor-specific options.
MotorClient and MotorReplicaSetClient have an option max_pool_size . It used to mean “minimum idle sockets to keep open”, but its meaning has changed to “maximum sockets open per host.” Once this limit is reached, operations will pause waiting for a socket to become available. Therefore the default has been raised from 10 to 100. If you pass a value for max_pool_size make sure it’s large enough for the expected load. (Sockets are only opened when needed, so there’s no cost to having a max_pool_size larger than necessary. Err towards a larger value.) If you’ve been accepting the default, continue to do so.
max_pool_size is now synonymous with Motor’s special max_concurrent option, so max_concurrent has been removed.
max_wait_time has been renamed waitQueueTimeoutMS for consistency with PyMongo. If you pass max_wait_time , rename it and multiply by 1000.
The MotorPoolTimeout exception is gone; catch PyMongo’s ConnectionFailure instead.
Motor can take advantage of Tornado 3’s asynchronous resolver interface . By default, Motor still uses blocking DNS, but you can enable non-blocking lookup with a threaded resolver:
Resolver . configure ( 'tornado.netutil.ThreadedResolver' )
Or install pycares and use the c-ares resolver:
Resolver . configure ( 'tornado.platform.caresresolver.CaresResolver' )
The MotorCursor.tail method has been removed. It was complex, diverged from PyMongo’s feature set, and encouraged overuse of MongoDB capped collections as message queues when a purpose-built message queue is more appropriate. An example of tailing a capped collection is provided instead: Motor Tailable Cursor Example .
is_locked has been removed since calling it from Motor would be bizarre. If you called MotorClient.is_locked like:
locked = yield motor . Op ( client . is_locked )
you should now do:
result = yield client . admin . current_op () locked = bool ( result . get ( 'fsyncLock' , None ))
The result is True only if an administrator has called fsyncLock on the mongod. It is unlikely that you have any use for this.
get_gridfs_file() now returns a Future instead of accepting a callback.
The introduction of a Futures-based API is the most pervasive new feature. In addition Motor 0.2 includes new features from PyMongo 2.6 and 2.7:
MotorCollection.aggregate() can return a cursor.
Support for all current MongoDB authentication mechanisms (see PyMongo’s authentication examples ).
A new MotorCollection.parallel_scan() method.
An API for bulk writes .
Support for wire protocol changes in MongoDB 2.6.
The ability to specify a server-side timeout for operations with max_time_ms() .
A new MotorGridFS.find() method for querying GridFS.
MotorReplicaSetClient.open threw an error if called without a callback.
MotorCursor.to_list ignored SON manipulators . (Thanks to Eren Güven for the report and the fix.)
The full list is in Jira .
Fixes innocuous unittest failures when running against Tornado 3.1.1.
Fixes innocuous unittest failures when running against Tornado 3.1.1.
Fixes issue MOTOR-12 by pinning its PyMongo dependency to PyMongo version 2.5.0 exactly.
Fixes issue MOTOR-12 by pinning its PyMongo dependency to PyMongo version 2.5.0 exactly.
Motor relies on some of PyMongo’s internal details, so changes to PyMongo can break Motor, and a change in PyMongo 2.5.1 did. Eventually PyMongo will expose stable hooks for Motor to use, but for now I changed Motor’s dependency from PyMongo>=2.4.2 to PyMongo==2.5.0 .
Changelog
Motor 2.4
Issues Resolved
Motor 2.3.1
Issues Resolved
Motor 2.3
Issues Resolved
Motor 2.2
Issues Resolved
Motor 2.1
Issues Resolved
Motor 2.0
Motor 1.3.1
Motor 1.3.0
Motor 1.2.5
Motor 1.2.4
Motor 1.2.3
Motor 1.2.2
Motor 1.2.1
Motor 1.2
Motor 1.1
Motor 1.0
MotorReplicaSetClient is removed
New features
MotorClient changes
MotorCollection changes
Changes to find() and find_one()
MotorCursor
GridFS
MotorGridOutCursor
MotorGridIn
MotorGridOut
Documentation
Motor 0.7
MotorClient changes
MotorReplicaSetClient changes
MotorDatabase changes
MotorCollection changes
GridFS changes
Bugfix
Motor 0.6.2
Motor 0.6.1
Motor 0.6
motor_asyncio and motor_tornado submodules
Database and collection names with leading underscores
Motor 0.5
asyncio
Python 3.5
async and await
aggregate()
Deprecations
Cursor slicing
SSL hostname validation error
Configuring uuid_subtype
Motor 0.4.1
Motor 0.4
Motor 0.3.3
Motor 0.3.2
Motor 0.3.1
Motor 0.3
Motor 0.2.1
Motor 0.2
Changes in Dependencies
API Changes
open_sync
Futures
to_list
Connection Pooling
DNS
MotorCursor.tail
MotorClient.is_locked
GridFSHandler
New Features
Bugfixes
Motor 0.1.2
Motor 0.1.1
Client-Side Field Level Encryption
Motor 2.0 Migration Guide
index
modules |
next |
previous |
Motor 2.4.0 documentation »
© Copyright 2016-present MongoDB, Inc.. Created using Sphinx 1.8.5.
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →